@ianmenethil/zp-devicefp 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,8 +20,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ CORE_SIGNALS: () => CORE_SIGNALS,
24
+ DEFAULT_FONT_LIST: () => DEFAULT_FONT_LIST,
25
+ DEFAULT_PERMISSION_NAMES: () => DEFAULT_PERMISSION_NAMES,
26
+ DEFAULT_TIMEOUT_MS: () => DEFAULT_TIMEOUT_MS,
27
+ DEFAULT_UA_HINTS: () => DEFAULT_UA_HINTS,
28
+ EXTENDED_SIGNALS: () => EXTENDED_SIGNALS,
23
29
  LIBRARY_VERSION: () => LIBRARY_VERSION,
24
30
  SCHEMA_VERSION: () => SCHEMA_VERSION,
31
+ SYNC_SIGNALS: () => SYNC_SIGNALS,
25
32
  createFingerprintClient: () => createFingerprintClient
26
33
  });
27
34
  module.exports = __toCommonJS(index_exports);
@@ -50,6 +57,35 @@ function hasCanvas(env) {
50
57
  return Boolean(env.document?.createElement?.("canvas").getContext);
51
58
  }
52
59
 
60
+ // src/signals/adblock.ts
61
+ var adblockCollector = {
62
+ name: "adblock",
63
+ tier: "extended",
64
+ supportsSync: false,
65
+ async collect(context) {
66
+ const started = now(context.env);
67
+ const doc = context.env.document;
68
+ if (!doc || !hasDom(context.env)) {
69
+ return { status: "unsupported", durationMs: now(context.env) - started };
70
+ }
71
+ return new Promise((resolve) => {
72
+ const bait = doc.createElement("div");
73
+ bait.innerHTML = "\xA0";
74
+ bait.className = "adsbox";
75
+ doc.body.appendChild(bait);
76
+ setTimeout(() => {
77
+ const adblockEnabled = bait.offsetHeight === 0;
78
+ doc.body.removeChild(bait);
79
+ resolve({
80
+ status: "ok",
81
+ durationMs: now(context.env) - started,
82
+ value: { adblockEnabled }
83
+ });
84
+ }, 100);
85
+ });
86
+ }
87
+ };
88
+
53
89
  // src/signals/audio.ts
54
90
  function getOfflineAudioContext(env) {
55
91
  const g = env;
@@ -168,7 +204,9 @@ var EXTENDED_SIGNALS = [
168
204
  "paymentSupport",
169
205
  "referrerInfo",
170
206
  "navigationInfo",
171
- "riskSignals"
207
+ "riskSignals",
208
+ "adblock",
209
+ "geolocation"
172
210
  ];
173
211
  var SYNC_SIGNALS = [
174
212
  "ua",
@@ -187,16 +225,76 @@ var SYNC_SIGNALS = [
187
225
  ];
188
226
  var DEFAULT_TIMEOUT_MS = 1500;
189
227
  var DEFAULT_FONT_LIST = [
228
+ "Andale Mono",
229
+ "American Typewriter",
230
+ "Apple Chancery",
190
231
  "Arial",
191
- "Helvetica Neue",
192
- "Times New Roman",
193
- "Georgia",
232
+ "Arial Black",
233
+ "Arial Narrow",
234
+ "Arial Rounded MT Bold",
235
+ "Baskerville",
236
+ "Book Antiqua",
237
+ "Bookman Old Style",
238
+ "Bradley Hand ITC",
239
+ "Calibri",
240
+ "Cambria",
241
+ "Candara",
242
+ "Century",
243
+ "Century Gothic",
244
+ "Century Schoolbook",
245
+ "Chalkboard",
246
+ "Charcoal",
247
+ "Cochin",
248
+ "Comic Sans MS",
249
+ "Consolas",
250
+ "Constantia",
251
+ "Corbel",
252
+ "Courier",
194
253
  "Courier New",
254
+ "Franklin Gothic Medium",
255
+ "Futura",
256
+ "Garamond",
257
+ "Geneva",
258
+ "Georgia",
259
+ "Gill Sans",
260
+ "Gill Sans MT",
261
+ "Helvetica",
262
+ "Hoefler Text",
263
+ "Impact",
264
+ "Lucida Bright",
265
+ "Lucida Console",
266
+ "Lucida Grande",
267
+ "Lucida Sans",
268
+ "MS Gothic",
269
+ "MS PGothic",
270
+ "MS Serif",
271
+ "MS UI Gothic",
272
+ "Meiryo",
273
+ "Meiryo UI",
274
+ "Monaco",
275
+ "Monotype Corsiva",
276
+ "New York",
277
+ "Optima",
278
+ "Palatino",
279
+ "Palatino Linotype",
280
+ "Papyrus",
281
+ "Plantagenet Cherokee",
282
+ "Segoe Print",
283
+ "Segoe Script",
284
+ "Segoe UI",
285
+ "Segoe UI Light",
286
+ "Segoe UI Semibold",
287
+ "Segoe UI Symbol",
288
+ "Symbol",
289
+ "Tahoma",
290
+ "Times",
291
+ "Times New Roman",
195
292
  "Trebuchet MS",
196
293
  "Verdana",
197
- "Tahoma",
198
- "Impact",
199
- "Comic Sans MS"
294
+ "Wingdings",
295
+ "Wingdings 2",
296
+ "Wingdings 3",
297
+ "Zapfino"
200
298
  ];
201
299
  var DEFAULT_PERMISSION_NAMES = ["geolocation", "notifications", "camera", "microphone"];
202
300
  var DEFAULT_UA_HINTS = [
@@ -324,6 +422,44 @@ var frameInfoCollector = {
324
422
  }
325
423
  };
326
424
 
425
+ // src/signals/geolocation.ts
426
+ var geolocationCollector = {
427
+ name: "geolocation",
428
+ tier: "extended",
429
+ supportsSync: false,
430
+ async collect(context) {
431
+ const started = now(context.env);
432
+ const nav = context.env.navigator;
433
+ if (!nav?.geolocation) {
434
+ return { status: "unsupported", durationMs: now(context.env) - started };
435
+ }
436
+ return new Promise((resolve) => {
437
+ nav.geolocation.getCurrentPosition(
438
+ (pos) => {
439
+ resolve({
440
+ status: "ok",
441
+ durationMs: now(context.env) - started,
442
+ value: {
443
+ latitude: pos.coords.latitude,
444
+ longitude: pos.coords.longitude,
445
+ accuracy: pos.coords.accuracy
446
+ }
447
+ });
448
+ },
449
+ (err) => {
450
+ resolve({
451
+ // PERMISSION_DENIED = 1
452
+ status: err.code === 1 ? "blocked" : "error",
453
+ durationMs: now(context.env) - started,
454
+ error: err.message
455
+ });
456
+ },
457
+ { timeout: context.options.timeoutMs, maximumAge: 6e4 }
458
+ );
459
+ });
460
+ }
461
+ };
462
+
327
463
  // src/signals/hardware.ts
328
464
  var hardwareCollector = {
329
465
  name: "hardware",
@@ -339,6 +475,17 @@ var hardwareCollector = {
339
475
  if (!nav) {
340
476
  return { status: "unsupported", durationMs: now(context.env) - started };
341
477
  }
478
+ const doc = context.env.document;
479
+ const g = context.env.global;
480
+ let touchEventCreationSuccessful = false;
481
+ try {
482
+ if (doc) {
483
+ doc.createEvent("TouchEvent");
484
+ touchEventCreationSuccessful = true;
485
+ }
486
+ } catch {
487
+ }
488
+ const onTouchStartAvailable = g != null && "ontouchstart" in g;
342
489
  return {
343
490
  status: "ok",
344
491
  durationMs: now(context.env) - started,
@@ -346,7 +493,9 @@ var hardwareCollector = {
346
493
  hardwareConcurrency: nav.hardwareConcurrency,
347
494
  deviceMemory: nav.deviceMemory,
348
495
  platform: nav.platform,
349
- maxTouchPoints: nav.maxTouchPoints
496
+ maxTouchPoints: nav.maxTouchPoints,
497
+ touchEventCreationSuccessful,
498
+ onTouchStartAvailable
350
499
  }
351
500
  };
352
501
  }
@@ -368,28 +517,36 @@ var localeCollector = {
368
517
  if (!nav || !intl) {
369
518
  return { status: "unsupported", durationMs: now(context.env) - started };
370
519
  }
371
- const formatter = new intl.DateTimeFormat();
372
- const options = formatter.resolvedOptions();
373
- const numberFormatter = new intl.NumberFormat(nav.language);
374
- const relativeTimeFormatter = typeof intl.RelativeTimeFormat === "function" ? new intl.RelativeTimeFormat(nav.language, { numeric: "auto" }) : void 0;
375
- const sampleDate = new Date(Date.UTC(2024, 0, 2, 3, 4, 5));
376
- return {
377
- status: "ok",
378
- durationMs: now(context.env) - started,
379
- value: {
380
- language: nav.language,
381
- languages: nav.languages,
382
- locale: options.locale,
383
- calendar: options.calendar,
384
- numberingSystem: options.numberingSystem,
385
- timeZone: options.timeZone,
386
- hourCycle: options.hourCycle,
387
- timeZoneOffsetMinutes: sampleDate.getTimezoneOffset(),
388
- formattedNumber: numberFormatter.format(123456.789),
389
- formattedDate: formatter.format(sampleDate),
390
- formattedRelativeDay: relativeTimeFormatter?.format(-1, "day")
391
- }
392
- };
520
+ try {
521
+ const formatter = new intl.DateTimeFormat();
522
+ const options = formatter.resolvedOptions();
523
+ const numberFormatter = new intl.NumberFormat(nav.language);
524
+ const relativeTimeFormatter = typeof intl.RelativeTimeFormat === "function" ? new intl.RelativeTimeFormat(nav.language, { numeric: "auto" }) : void 0;
525
+ const sampleDate = new Date(Date.UTC(2024, 0, 2, 3, 4, 5));
526
+ return {
527
+ status: "ok",
528
+ durationMs: now(context.env) - started,
529
+ value: {
530
+ language: nav.language,
531
+ languages: nav.languages,
532
+ locale: options.locale,
533
+ calendar: options.calendar,
534
+ numberingSystem: options.numberingSystem,
535
+ timeZone: options.timeZone,
536
+ hourCycle: options.hourCycle,
537
+ timeZoneOffsetMinutes: sampleDate.getTimezoneOffset(),
538
+ formattedNumber: numberFormatter.format(123456.789),
539
+ formattedDate: formatter.format(sampleDate),
540
+ formattedRelativeDay: relativeTimeFormatter?.format(-1, "day")
541
+ }
542
+ };
543
+ } catch (error) {
544
+ return {
545
+ status: "error",
546
+ durationMs: now(context.env) - started,
547
+ error: error instanceof Error ? error.message : String(error)
548
+ };
549
+ }
393
550
  }
394
551
  };
395
552
 
@@ -700,6 +857,7 @@ var screenCollector = {
700
857
  if (!screen2) {
701
858
  return { status: "unsupported", durationMs: now(context.env) - started };
702
859
  }
860
+ const orientation = screen2.orientation;
703
861
  return {
704
862
  status: "ok",
705
863
  durationMs: now(context.env) - started,
@@ -710,10 +868,24 @@ var screenCollector = {
710
868
  availHeight: screen2.availHeight,
711
869
  colorDepth: screen2.colorDepth,
712
870
  pixelDepth: screen2.pixelDepth,
713
- orientationType: screen2.orientation.type,
714
- orientationAngle: screen2.orientation.angle,
871
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- orientation is optional at runtime despite the Screen intersection
872
+ ...orientation ? { orientationType: orientation.type, orientationAngle: orientation.angle } : {},
715
873
  maxTouchPoints: nav?.maxTouchPoints ?? 0,
874
+ resolution: `${String(screen2.width)}x${String(screen2.height)}`,
875
+ ratio: screen2.height > 0 ? Math.round(screen2.width / screen2.height * 1e10) / 1e10 : 0,
716
876
  devicePixelRatio: typeof runtime.devicePixelRatio === "number" ? runtime.devicePixelRatio : void 0,
877
+ // Fingerprint2 / Cardinal Commerce has_lied_resolution: availWidth never exceeds width on a real device
878
+ fakedResolution: screen2.availWidth > screen2.width || screen2.availHeight > screen2.height,
879
+ // Cardinal Commerce CCAScreenSize — outerWidth/outerHeight bucket code
880
+ ccaScreenSize: (() => {
881
+ const w = typeof runtime.outerWidth === "number" ? runtime.outerWidth : 0;
882
+ const h = typeof runtime.outerHeight === "number" ? runtime.outerHeight : 0;
883
+ if (w < 390) return "01";
884
+ if (w < 500) return "02";
885
+ if (w < 600) return "03";
886
+ if (h < 600) return "04";
887
+ return "02";
888
+ })(),
717
889
  colorGamutP3: getMediaPreference(runtime, "(color-gamut: p3)"),
718
890
  prefersReducedMotion: getMediaPreference(runtime, "(prefers-reduced-motion: reduce)"),
719
891
  prefersContrastMore: getMediaPreference(runtime, "(prefers-contrast: more)"),
@@ -780,6 +952,16 @@ var uaCollector = {
780
952
  if (!nav) {
781
953
  return { status: "unsupported", durationMs: now(context.env) - started };
782
954
  }
955
+ let plugins = [];
956
+ try {
957
+ plugins = Array.from(nav.plugins).map((p) => {
958
+ const mimes = Array.from({ length: p.length }, (_, i) => p.item(i)).filter((m) => m !== null).map((m) => `${m.type}~${m.suffixes}`).join(",");
959
+ return `${p.name}::${p.description}::${mimes}`;
960
+ });
961
+ } catch {
962
+ }
963
+ const rawDnt = nav.doNotTrack ?? context.env.global.doNotTrack ?? null;
964
+ const doNotTrack = rawDnt === "1" ? "enabled" : rawDnt === "0" ? "disabled" : rawDnt ?? "not_set";
783
965
  return {
784
966
  status: "ok",
785
967
  durationMs: now(context.env) - started,
@@ -791,7 +973,9 @@ var uaCollector = {
791
973
  webdriver: nav.webdriver,
792
974
  maxTouchPoints: nav.maxTouchPoints,
793
975
  cookieEnabled: nav.cookieEnabled,
794
- vendorSub: nav.vendorSub
976
+ vendorSub: nav.vendorSub,
977
+ doNotTrack,
978
+ plugins
795
979
  }
796
980
  };
797
981
  }
@@ -948,7 +1132,9 @@ var signalCollectors = [
948
1132
  paymentSupportCollector,
949
1133
  referrerInfoCollector,
950
1134
  navigationInfoCollector,
951
- riskSignalsCollector
1135
+ riskSignalsCollector,
1136
+ adblockCollector,
1137
+ geolocationCollector
952
1138
  ];
953
1139
  var collectorMap = new Map(signalCollectors.map((collector) => [collector.name, collector]));
954
1140
 
@@ -962,6 +1148,13 @@ function asString(value) {
962
1148
  function asNumber(value) {
963
1149
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
964
1150
  }
1151
+ function canonicalizeLegacyPlatform(legacyPlatform) {
1152
+ if (legacyPlatform.startsWith("win")) return "windows";
1153
+ if (legacyPlatform.startsWith("mac")) return "macos";
1154
+ if (/cros|chrome/.test(legacyPlatform)) return "chrome os";
1155
+ if (/linux|x11/.test(legacyPlatform)) return "linux";
1156
+ return legacyPlatform;
1157
+ }
965
1158
  function analyseSignals(signals) {
966
1159
  const anomalies = [];
967
1160
  const automationHints = [];
@@ -983,8 +1176,12 @@ function analyseSignals(signals) {
983
1176
  if (userAgent.includes("headless")) {
984
1177
  automationHints.push("headless_user_agent");
985
1178
  }
986
- if (platform && hintPlatform && !platform.includes(hintPlatform) && !hintPlatform.includes(platform)) {
987
- anomalies.push("ua_platform_mismatch");
1179
+ if (platform && hintPlatform) {
1180
+ const canonicalLegacy = canonicalizeLegacyPlatform(platform);
1181
+ const linuxFamilyOk = canonicalLegacy === "linux" && (hintPlatform === "linux" || hintPlatform === "android" || hintPlatform === "chrome os");
1182
+ if (!linuxFamilyOk && canonicalLegacy !== hintPlatform) {
1183
+ anomalies.push("ua_platform_mismatch");
1184
+ }
988
1185
  }
989
1186
  if (userAgent.includes("iphone") && maxTouchPoints === 0) {
990
1187
  anomalies.push("touch_claim_without_touch_points");
@@ -1004,10 +1201,16 @@ function analyseSignals(signals) {
1004
1201
  const anomalyPenalty = anomalies.length * 0.12;
1005
1202
  const automationPenalty = automationHints.length * 0.18;
1006
1203
  const score = Math.max(0, Math.min(1, Number((1 - anomalyPenalty - automationPenalty).toFixed(3))));
1204
+ const fakedOS = anomalies.includes("ua_platform_mismatch");
1205
+ const riskVal = asRecord(signals.riskSignals?.value);
1206
+ const headlessHints = Array.isArray(riskVal?.headlessHints) ? riskVal.headlessHints : [];
1207
+ const fakedBrowser = headlessHints.includes("missing-chrome-object");
1007
1208
  return {
1008
1209
  score,
1009
1210
  anomalies,
1010
- automationHints
1211
+ automationHints,
1212
+ fakedOS,
1213
+ fakedBrowser
1011
1214
  };
1012
1215
  }
1013
1216
 
@@ -1077,7 +1280,9 @@ var SIGNAL_WEIGHTS = {
1077
1280
  paymentSupport: 0.2,
1078
1281
  referrerInfo: 0.3,
1079
1282
  navigationInfo: 0.4,
1080
- riskSignals: 0.7
1283
+ riskSignals: 0.7,
1284
+ adblock: 0.3,
1285
+ geolocation: 0.5
1081
1286
  };
1082
1287
  function computeConfidence(signals, antiSpoof) {
1083
1288
  let earned = 0;
@@ -1299,28 +1504,9 @@ function resolveSignalSet(options, mode = "async") {
1299
1504
  return included.filter((signal) => !excluded.has(signal));
1300
1505
  }
1301
1506
 
1302
- // src/core/upload.ts
1303
- async function uploadFingerprint(env, result, options) {
1304
- const fetchImpl = options.endpoint && env.fetch;
1305
- if (!fetchImpl) {
1306
- throw new Error("Fetch is not available in this runtime.");
1307
- }
1308
- return fetchImpl(options.endpoint, {
1309
- method: "POST",
1310
- headers: {
1311
- "content-type": "application/json",
1312
- ...options.headers
1313
- },
1314
- body: JSON.stringify({
1315
- fingerprint: result,
1316
- ...options.bodyExtras
1317
- })
1318
- });
1319
- }
1320
-
1321
1507
  // src/version.ts
1322
- var LIBRARY_VERSION = "0.1.0";
1323
- var SCHEMA_VERSION = 1;
1508
+ var LIBRARY_VERSION = true ? "0.2.0" : "0.0.0-dev";
1509
+ var SCHEMA_VERSION = 2;
1324
1510
 
1325
1511
  // src/client.ts
1326
1512
  function toTimedOutResult(durationMs) {
@@ -1330,6 +1516,18 @@ function toTimedOutResult(durationMs) {
1330
1516
  error: "Signal collection timed out."
1331
1517
  };
1332
1518
  }
1519
+ function toErrorResult(durationMs, error) {
1520
+ return {
1521
+ status: "error",
1522
+ durationMs,
1523
+ error: error instanceof Error ? error.message : String(error)
1524
+ };
1525
+ }
1526
+ function debugLog(resolved, message) {
1527
+ if (resolved.debug) {
1528
+ console.debug(`[zp-devicefp] ${message}`);
1529
+ }
1530
+ }
1333
1531
  async function runCollectorWithTimeout(collector, env, options, warn) {
1334
1532
  const started = env.performance?.now?.() ?? Date.now();
1335
1533
  if (options.abortSignal?.aborted) {
@@ -1341,31 +1539,36 @@ async function runCollectorWithTimeout(collector, env, options, warn) {
1341
1539
  }
1342
1540
  let clearTimeoutHandle = () => {
1343
1541
  };
1542
+ let removeAbortListener = () => {
1543
+ };
1344
1544
  const timeoutPromise = new Promise((resolve) => {
1345
1545
  const timeout = setTimeout(() => {
1346
1546
  resolve(toTimedOutResult((env.performance?.now?.() ?? Date.now()) - started));
1347
1547
  }, options.timeoutMs);
1348
1548
  clearTimeoutHandle = () => clearTimeout(timeout);
1349
- options.abortSignal?.addEventListener(
1350
- "abort",
1351
- () => {
1352
- clearTimeoutHandle();
1353
- resolve({
1354
- status: "error",
1355
- durationMs: (env.performance?.now?.() ?? Date.now()) - started,
1356
- error: "Collection aborted."
1357
- });
1358
- },
1359
- { once: true }
1360
- );
1361
- });
1362
- const resultPromise = collector.collect({
1363
- env,
1364
- options,
1365
- warn
1549
+ const onAbort = () => {
1550
+ clearTimeoutHandle();
1551
+ resolve({
1552
+ status: "error",
1553
+ durationMs: (env.performance?.now?.() ?? Date.now()) - started,
1554
+ error: "Collection aborted."
1555
+ });
1556
+ };
1557
+ options.abortSignal?.addEventListener("abort", onAbort, { once: true });
1558
+ removeAbortListener = () => options.abortSignal?.removeEventListener("abort", onAbort);
1366
1559
  });
1560
+ const resultPromise = (async () => {
1561
+ try {
1562
+ return await collector.collect({ env, options, warn });
1563
+ } catch (error) {
1564
+ const result = toErrorResult((env.performance?.now?.() ?? Date.now()) - started, error);
1565
+ warn(`Signal "${collector.name}" threw: ${result.error ?? "unknown error"}`, collector.name);
1566
+ return result;
1567
+ }
1568
+ })();
1367
1569
  return Promise.race([resultPromise, timeoutPromise]).finally(() => {
1368
1570
  clearTimeoutHandle();
1571
+ removeAbortListener();
1369
1572
  });
1370
1573
  }
1371
1574
  function buildResult(signals, warnings, requestedSignals, elapsedMs) {
@@ -1427,6 +1630,7 @@ async function createFingerprintClient(options) {
1427
1630
  }
1428
1631
  const result = await runCollectorWithTimeout(collector, env, resolved, warn);
1429
1632
  collected[name] = result;
1633
+ debugLog(resolved, `${name}: ${result.status} (${String(result.durationMs)}ms)`);
1430
1634
  completed += 1;
1431
1635
  emitter.emit("progress", {
1432
1636
  completed,
@@ -1457,22 +1661,35 @@ async function createFingerprintClient(options) {
1457
1661
  warn(`Signal "${name}" is not available in synchronous mode.`, name);
1458
1662
  continue;
1459
1663
  }
1460
- collected[name] = collector.collectSync({
1461
- env,
1462
- options: resolved,
1463
- warn
1464
- });
1664
+ const signalStarted = env.performance?.now?.() ?? Date.now();
1665
+ let result;
1666
+ try {
1667
+ result = collector.collectSync({
1668
+ env,
1669
+ options: resolved,
1670
+ warn
1671
+ });
1672
+ } catch (error) {
1673
+ result = toErrorResult((env.performance?.now?.() ?? Date.now()) - signalStarted, error);
1674
+ warn(`Signal "${name}" threw: ${result.error ?? "unknown error"}`, name);
1675
+ }
1676
+ collected[name] = result;
1677
+ debugLog(resolved, `${name}: ${result.status} (${String(result.durationMs)}ms)`);
1465
1678
  }
1466
1679
  return buildResult(collected, warnings, signalNames, (env.performance?.now?.() ?? Date.now()) - started);
1467
- },
1468
- upload(result, uploadOptions) {
1469
- return uploadFingerprint(getBrowserEnv(), result, uploadOptions);
1470
1680
  }
1471
1681
  };
1472
1682
  }
1473
1683
  // Annotate the CommonJS export names for ESM import in node:
1474
1684
  0 && (module.exports = {
1685
+ CORE_SIGNALS,
1686
+ DEFAULT_FONT_LIST,
1687
+ DEFAULT_PERMISSION_NAMES,
1688
+ DEFAULT_TIMEOUT_MS,
1689
+ DEFAULT_UA_HINTS,
1690
+ EXTENDED_SIGNALS,
1475
1691
  LIBRARY_VERSION,
1476
1692
  SCHEMA_VERSION,
1693
+ SYNC_SIGNALS,
1477
1694
  createFingerprintClient
1478
1695
  });
@@ -17,7 +17,9 @@ export type SignalName =
17
17
  | 'paymentSupport'
18
18
  | 'referrerInfo'
19
19
  | 'navigationInfo'
20
- | 'riskSignals';
20
+ | 'riskSignals'
21
+ | 'adblock'
22
+ | 'geolocation';
21
23
 
22
24
  export type SignalStatus = 'ok' | 'unsupported' | 'blocked' | 'timeout' | 'error';
23
25
 
@@ -32,6 +34,8 @@ export interface AntiSpoofReport {
32
34
  score: number;
33
35
  anomalies: string[];
34
36
  automationHints: string[];
37
+ fakedOS: boolean;
38
+ fakedBrowser: boolean;
35
39
  }
36
40
 
37
41
  export interface FingerprintResult {
@@ -61,12 +65,6 @@ export interface CollectorDiagnostics {
61
65
  elapsedMs: number;
62
66
  }
63
67
 
64
- export interface UploadOptions {
65
- endpoint: string;
66
- headers?: Record<string, string>;
67
- bodyExtras?: Record<string, unknown>;
68
- }
69
-
70
68
  export interface ProgressEvent {
71
69
  completed: number;
72
70
  total: number;
@@ -92,10 +90,25 @@ export interface EventPayloadMap {
92
90
  export interface FingerprintClient {
93
91
  collect(options?: CollectOptions): Promise<FingerprintResult>;
94
92
  collectSync(options?: Omit<CollectOptions, 'timeoutMs' | 'abortSignal'>): FingerprintResult;
95
- upload(result: FingerprintResult, options: UploadOptions): Promise<Response>;
96
93
  on<K extends keyof EventPayloadMap>(event: K, cb: (payload: EventPayloadMap[K]) => void): () => void;
97
94
  }
98
95
 
99
96
  export declare const LIBRARY_VERSION: string;
100
97
  export declare const SCHEMA_VERSION: number;
98
+ export declare const CORE_SIGNALS: SignalName[];
99
+ export declare const EXTENDED_SIGNALS: SignalName[];
100
+ export declare const SYNC_SIGNALS: SignalName[];
101
+ export declare const DEFAULT_TIMEOUT_MS: number;
102
+ export declare const DEFAULT_FONT_LIST: string[];
103
+ export declare const DEFAULT_PERMISSION_NAMES: readonly ['geolocation', 'notifications', 'camera', 'microphone'];
104
+ export declare const DEFAULT_UA_HINTS: readonly [
105
+ 'architecture',
106
+ 'bitness',
107
+ 'formFactors',
108
+ 'fullVersionList',
109
+ 'model',
110
+ 'platform',
111
+ 'platformVersion',
112
+ 'wow64',
113
+ ];
101
114
  export declare function createFingerprintClient(options?: CollectOptions): Promise<FingerprintClient>;