Skip to main content

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:

  1. loadWebDataCollector() returns a collector instance
  2. collector.get() yields raw structured data
  3. mapDataCollector(result) normalizes shape
  4. 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 KeyScenario
theia.meta_fallbackCrypto unavailable or exception in meta generation
theia.sdk_version_fallbackInvalid kSdkVersion format
theia.web_version_fallbackInvalid kWebVersion format
theia.properties_fallbackFailure 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