Theia
Theia provides low-level device / environment telemetry data used for abuse prevention, fraud intelligence, and risk scoring. It generates a compact meta payload plus a richer set of browser-derived properties (via @traveloka/web-data-collector).
Two primary public methods:
Theia.getMeta(): { c; r; a; d; t; e }– fast, synchronous metadata (strings)Theia.getProperties(): Promise<Record<string,string>>– async enrichment map
Meta Structure
| Field | Meaning | Source | Notes |
| ----- | ------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------ | ------------ | -------- |
| c | Interface code (client interface + entropy) | Random byte + interface bit pattern | Distinguishes desktop vs mobile via low 2 bits (0b10 / 0b11) |
| r | Encoded SDK version | kSdkVersion semantic version → packed bits | Format: (major << 14) | (minor << 8) | patch |
| a | Encoded Web version + entropy | kWebVersion + random byte | Format: (major << 18) | (minor << 8) | random8 |
| d | Device code | 32 bits crypto-random | Not stable across reloads (intentional) |
| t | Timestamp (ms) | Date.now() | Generation time |
| e | Checksum | JSBI big-int xor composition | Guards against simple tampering |
If secure randomness is unavailable (SSR or very old browsers), an all-empty default meta is returned and a warning is logged: theia.meta_fallback.
Property Collection
getProperties() loads a web data collector:
loadWebDataCollector()returns a collector instancecollector.get()yields raw structured datamapDataCollector(result)normalizes shape- Values are filtered and stringified (objects → JSON)
Failures produce a fallback {} and log theia.properties_fallback.
Internal Versioning
Constants:
kWebVersion = "1.0.0"kSdkVersion = "2012.2.29"
They are encoded into numeric strings to reduce payload verbosity and facilitate downstream bitwise parsing.
Randomness & Security
All entropy uses window.crypto.getRandomValues. If not present, meta falls back to defaults instead of unsafe PRNG. This protects consistency and avoids leaking predictable identifiers.
Checksum Algorithm
Pseudo steps:
checksum = 0n
checksum ^= (c & 0xff) << 48
checksum ^= r << 32
checksum ^= a << 16
checksum ^= d
// mix timestamp t with a right-shifted self-xor
checksum ^= (t ^ (t >> 33))
(Actual operations use JSBI for BigInt safety and portability.)
Usage
Basic (Client Only)
import { Theia } from '@traveloka/core';
const meta = Theia.getMeta(); // Sync
const props = await Theia.getProperties(); // Async
sendToRiskService({ meta, properties: props });
Combined With Collector Component
Use <TheiaCollector /> (documented separately) to auto-submit on first eligible page view.
Error / Fallback Logging Keys
| Log Key | Scenario |
|---|---|
theia.meta_fallback | Crypto unavailable or exception in meta generation |
theia.sdk_version_fallback | Invalid kSdkVersion format |
theia.web_version_fallback | Invalid kWebVersion format |
theia.properties_fallback | Failure retrieving or mapping extended properties |
SSR Considerations
getMeta()should be called only client-side (needs crypto). On server it will return default values and log a fallback.getProperties()also requires browser APIs; avoid calling during SSR.
Performance Notes
getMeta()is O(1) and fast (single crypto calls + simple bit packing)getProperties()cost depends on the underlying collector; call once and cache if needed
Testing Patterns
Mock randomness and the collector:
Object.defineProperty(window, 'crypto', {
value: { getRandomValues: b => (b[0] = 123) },
});
Mock @traveloka/web-data-collector:
jest.mock('@traveloka/web-data-collector', () => ({
load: () => Promise.resolve({ get: () => ({ a: 1, b: { c: 2 } }) }),
mapDataCollector: r => r,
}));
Observability Checklist
Track ratios of:
- Fallback meta generations vs total calls
- Properties collection failures
- Distribution of interface codes (
c % 4) to catch skew (deployment issues)
Extensibility Guidelines
- Add new meta fields only if they can be deterministically encoded & versioned
- Avoid introducing user-identifying PII into properties
- Keep checksum logic backwards-compatible; changing it requires downstream coordination
Last updated: 2025-09-24