vesant-sdk 1.1.1 → 1.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.
- package/dist/{client-BfeDYmrZ.d.mts → client-BIfLMfuC.d.mts} +24 -0
- package/dist/{client-i5QtnFIa.d.ts → client-BWp5FI3x.d.ts} +24 -0
- package/dist/compliance/index.d.mts +2 -2
- package/dist/compliance/index.d.ts +2 -2
- package/dist/compliance/index.js +286 -2
- package/dist/compliance/index.js.map +1 -1
- package/dist/compliance/index.mjs +286 -2
- package/dist/compliance/index.mjs.map +1 -1
- package/dist/geolocation/index.d.mts +2 -2
- package/dist/geolocation/index.d.ts +2 -2
- package/dist/geolocation/index.js +310 -250
- package/dist/geolocation/index.js.map +1 -1
- package/dist/geolocation/index.mjs +310 -250
- package/dist/geolocation/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +311 -251
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +311 -251
- package/dist/index.mjs.map +1 -1
- package/dist/kyc/core.js +1 -1
- package/dist/kyc/core.js.map +1 -1
- package/dist/kyc/core.mjs +1 -1
- package/dist/kyc/core.mjs.map +1 -1
- package/dist/kyc/index.js +1 -1
- package/dist/kyc/index.js.map +1 -1
- package/dist/kyc/index.mjs +1 -1
- package/dist/kyc/index.mjs.map +1 -1
- package/dist/react.d.mts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +29 -3
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +29 -3
- package/dist/react.mjs.map +1 -1
- package/dist/risk-profile/index.js +1 -1
- package/dist/risk-profile/index.js.map +1 -1
- package/dist/risk-profile/index.mjs +1 -1
- package/dist/risk-profile/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -73,6 +73,10 @@ type CipherTextReason = 'registration' | 'login' | 'transaction' | 'interval_che
|
|
|
73
73
|
interface CipherTextOptions {
|
|
74
74
|
/** Reason for collection (required) */
|
|
75
75
|
reason: CipherTextReason;
|
|
76
|
+
/** Public signing key (pk_) for HMAC signing (produces v02 signed cipherText) */
|
|
77
|
+
signingKey?: string;
|
|
78
|
+
/** @deprecated Use signingKey instead. API key for HMAC signing (backward compat) */
|
|
79
|
+
apiKey?: string;
|
|
76
80
|
/** Request GPS location (default: false) */
|
|
77
81
|
requestLocation?: boolean;
|
|
78
82
|
/** GPS timeout in milliseconds (default: 10000) */
|
|
@@ -449,6 +453,8 @@ interface GeolocationConfigResponse {
|
|
|
449
453
|
registration: boolean;
|
|
450
454
|
transaction: boolean;
|
|
451
455
|
};
|
|
456
|
+
/** Public signing key (pk_) for client-side HMAC signing */
|
|
457
|
+
signing_key?: string;
|
|
452
458
|
}
|
|
453
459
|
interface GeolocationClientConfig {
|
|
454
460
|
/** Base URL of the API Gateway (e.g., "https://api.example.com") */
|
|
@@ -736,6 +742,7 @@ interface UseLocationCaptureResult {
|
|
|
736
742
|
* transient failures gracefully.
|
|
737
743
|
*/
|
|
738
744
|
declare class GeolocationClient extends BaseClient {
|
|
745
|
+
private cachedSigningKey?;
|
|
739
746
|
constructor(config: GeolocationClientConfig);
|
|
740
747
|
/**
|
|
741
748
|
* Verify an IP address and check compliance
|
|
@@ -964,6 +971,23 @@ declare class GeolocationClient extends BaseClient {
|
|
|
964
971
|
* ```
|
|
965
972
|
*/
|
|
966
973
|
captureLocation(token: string, capture: LocationCaptureRequest, requestOptions?: RequestOptions): Promise<LocationCaptureResponse>;
|
|
974
|
+
/**
|
|
975
|
+
* Generate a signed cipherText containing device and location data.
|
|
976
|
+
*
|
|
977
|
+
* Automatically passes the client's API key for HMAC signing (v02 format).
|
|
978
|
+
* If no API key is configured, falls back to unsigned v01 format.
|
|
979
|
+
*
|
|
980
|
+
* @param options - Options for cipherText generation
|
|
981
|
+
* @param gpsConfig - Optional GPS config (from getGPSConfig)
|
|
982
|
+
* @returns CipherText result with the signed string
|
|
983
|
+
*
|
|
984
|
+
* @example
|
|
985
|
+
* ```typescript
|
|
986
|
+
* const result = await client.generateCipherText({ reason: 'login' });
|
|
987
|
+
* console.log(result.cipherText); // v02 signed cipherText
|
|
988
|
+
* ```
|
|
989
|
+
*/
|
|
990
|
+
generateCipherText(options: Omit<CipherTextOptions, 'apiKey' | 'signingKey'>, gpsConfig?: GeolocationConfigResponse): Promise<CipherTextResult>;
|
|
967
991
|
}
|
|
968
992
|
|
|
969
993
|
export { type UseLocationRequestsOptions as $, type AlertStatus as A, type APIError as B, type CipherTextPayload as C, type DeviceFingerprintRequest as D, type GeolocationConfigResponse as E, type GeolocationClientConfig as F, GeolocationClient as G, type UseGeolocationOptions as H, type UseGeolocationResult as I, type JurisdictionConfig as J, type UseAlertsOptions as K, type LocationVerification as L, type UseAlertsResult as M, type LocationRequestStatus as N, type LocationRequestChannel as O, type LocationRequest as P, type CreateLocationRequestRequest as Q, type LocationRequestResult as R, type LocationRequestFilters as S, type LocationRequestListResponse as T, type UpdateJurisdictionRequest as U, type ValidateCipherTextRequest as V, type ResendLocationRequestRequest as W, type WiFiNetwork as X, type LocationCaptureRequest as Y, type LocationShareInfo as Z, type LocationCaptureResponse as _, type CipherTextReason as a, type UseLocationRequestsResult as a0, type UseLocationCaptureOptions as a1, type UseLocationCaptureResult as a2, type CipherTextOptions as b, type CipherTextResult as c, type DecryptedCipherText as d, type CipherTextCustomerData as e, type ValidateCipherTextResponse as f, type VerifyIPRequest as g, type GeoIPResult as h, type GeofenceEvaluation as i, type DeviceFingerprint as j, type DeviceTrustResult as k, type ComplianceCheckResponse as l, type AlertSeverity as m, type AlertType as n, type GeolocationAlert as o, type AlertFilters as p, type AlertListResponse as q, type DashboardMetrics as r, type CreateJurisdictionRequest as s, type GeofenceRuleType as t, type GeofenceAction as u, type GeofenceRule as v, type CreateGeofenceRuleRequest as w, type UpdateGeofenceRuleRequest as x, type UpdateDeviceTrustRequest as y, type GeolocationRecord as z };
|
|
@@ -73,6 +73,10 @@ type CipherTextReason = 'registration' | 'login' | 'transaction' | 'interval_che
|
|
|
73
73
|
interface CipherTextOptions {
|
|
74
74
|
/** Reason for collection (required) */
|
|
75
75
|
reason: CipherTextReason;
|
|
76
|
+
/** Public signing key (pk_) for HMAC signing (produces v02 signed cipherText) */
|
|
77
|
+
signingKey?: string;
|
|
78
|
+
/** @deprecated Use signingKey instead. API key for HMAC signing (backward compat) */
|
|
79
|
+
apiKey?: string;
|
|
76
80
|
/** Request GPS location (default: false) */
|
|
77
81
|
requestLocation?: boolean;
|
|
78
82
|
/** GPS timeout in milliseconds (default: 10000) */
|
|
@@ -449,6 +453,8 @@ interface GeolocationConfigResponse {
|
|
|
449
453
|
registration: boolean;
|
|
450
454
|
transaction: boolean;
|
|
451
455
|
};
|
|
456
|
+
/** Public signing key (pk_) for client-side HMAC signing */
|
|
457
|
+
signing_key?: string;
|
|
452
458
|
}
|
|
453
459
|
interface GeolocationClientConfig {
|
|
454
460
|
/** Base URL of the API Gateway (e.g., "https://api.example.com") */
|
|
@@ -736,6 +742,7 @@ interface UseLocationCaptureResult {
|
|
|
736
742
|
* transient failures gracefully.
|
|
737
743
|
*/
|
|
738
744
|
declare class GeolocationClient extends BaseClient {
|
|
745
|
+
private cachedSigningKey?;
|
|
739
746
|
constructor(config: GeolocationClientConfig);
|
|
740
747
|
/**
|
|
741
748
|
* Verify an IP address and check compliance
|
|
@@ -964,6 +971,23 @@ declare class GeolocationClient extends BaseClient {
|
|
|
964
971
|
* ```
|
|
965
972
|
*/
|
|
966
973
|
captureLocation(token: string, capture: LocationCaptureRequest, requestOptions?: RequestOptions): Promise<LocationCaptureResponse>;
|
|
974
|
+
/**
|
|
975
|
+
* Generate a signed cipherText containing device and location data.
|
|
976
|
+
*
|
|
977
|
+
* Automatically passes the client's API key for HMAC signing (v02 format).
|
|
978
|
+
* If no API key is configured, falls back to unsigned v01 format.
|
|
979
|
+
*
|
|
980
|
+
* @param options - Options for cipherText generation
|
|
981
|
+
* @param gpsConfig - Optional GPS config (from getGPSConfig)
|
|
982
|
+
* @returns CipherText result with the signed string
|
|
983
|
+
*
|
|
984
|
+
* @example
|
|
985
|
+
* ```typescript
|
|
986
|
+
* const result = await client.generateCipherText({ reason: 'login' });
|
|
987
|
+
* console.log(result.cipherText); // v02 signed cipherText
|
|
988
|
+
* ```
|
|
989
|
+
*/
|
|
990
|
+
generateCipherText(options: Omit<CipherTextOptions, 'apiKey' | 'signingKey'>, gpsConfig?: GeolocationConfigResponse): Promise<CipherTextResult>;
|
|
967
991
|
}
|
|
968
992
|
|
|
969
993
|
export { type UseLocationRequestsOptions as $, type AlertStatus as A, type APIError as B, type CipherTextPayload as C, type DeviceFingerprintRequest as D, type GeolocationConfigResponse as E, type GeolocationClientConfig as F, GeolocationClient as G, type UseGeolocationOptions as H, type UseGeolocationResult as I, type JurisdictionConfig as J, type UseAlertsOptions as K, type LocationVerification as L, type UseAlertsResult as M, type LocationRequestStatus as N, type LocationRequestChannel as O, type LocationRequest as P, type CreateLocationRequestRequest as Q, type LocationRequestResult as R, type LocationRequestFilters as S, type LocationRequestListResponse as T, type UpdateJurisdictionRequest as U, type ValidateCipherTextRequest as V, type ResendLocationRequestRequest as W, type WiFiNetwork as X, type LocationCaptureRequest as Y, type LocationShareInfo as Z, type LocationCaptureResponse as _, type CipherTextReason as a, type UseLocationRequestsResult as a0, type UseLocationCaptureOptions as a1, type UseLocationCaptureResult as a2, type CipherTextOptions as b, type CipherTextResult as c, type DecryptedCipherText as d, type CipherTextCustomerData as e, type ValidateCipherTextResponse as f, type VerifyIPRequest as g, type GeoIPResult as h, type GeofenceEvaluation as i, type DeviceFingerprint as j, type DeviceTrustResult as k, type ComplianceCheckResponse as l, type AlertSeverity as m, type AlertType as n, type GeolocationAlert as o, type AlertFilters as p, type AlertListResponse as q, type DashboardMetrics as r, type CreateJurisdictionRequest as s, type GeofenceRuleType as t, type GeofenceAction as u, type GeofenceRule as v, type CreateGeofenceRuleRequest as w, type UpdateGeofenceRuleRequest as x, type UpdateDeviceTrustRequest as y, type GeolocationRecord as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as DeviceFingerprintRequest, L as LocationVerification, P as LocationRequest, G as GeolocationClient, S as LocationRequestFilters, T as LocationRequestListResponse } from '../client-
|
|
2
|
-
export { Q as CreateLocationRequestRequest, Y as LocationCaptureRequest, _ as LocationCaptureResponse, O as LocationRequestChannel, R as LocationRequestResult, N as LocationRequestStatus, Z as LocationShareInfo, W as ResendLocationRequestRequest } from '../client-
|
|
1
|
+
import { D as DeviceFingerprintRequest, L as LocationVerification, P as LocationRequest, G as GeolocationClient, S as LocationRequestFilters, T as LocationRequestListResponse } from '../client-BIfLMfuC.mjs';
|
|
2
|
+
export { Q as CreateLocationRequestRequest, Y as LocationCaptureRequest, _ as LocationCaptureResponse, O as LocationRequestChannel, R as LocationRequestResult, N as LocationRequestStatus, Z as LocationShareInfo, W as ResendLocationRequestRequest } from '../client-BIfLMfuC.mjs';
|
|
3
3
|
import { RiskProfileClient } from '../risk-profile/index.mjs';
|
|
4
4
|
import { E as EntityType, e as CGSConfig, R as RequestOptions, P as PaginationParams } from '../types-BpKxSXGF.mjs';
|
|
5
5
|
import { C as CustomerProfile } from '../types-DKCQN4C5.mjs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as DeviceFingerprintRequest, L as LocationVerification, P as LocationRequest, G as GeolocationClient, S as LocationRequestFilters, T as LocationRequestListResponse } from '../client-
|
|
2
|
-
export { Q as CreateLocationRequestRequest, Y as LocationCaptureRequest, _ as LocationCaptureResponse, O as LocationRequestChannel, R as LocationRequestResult, N as LocationRequestStatus, Z as LocationShareInfo, W as ResendLocationRequestRequest } from '../client-
|
|
1
|
+
import { D as DeviceFingerprintRequest, L as LocationVerification, P as LocationRequest, G as GeolocationClient, S as LocationRequestFilters, T as LocationRequestListResponse } from '../client-BWp5FI3x.js';
|
|
2
|
+
export { Q as CreateLocationRequestRequest, Y as LocationCaptureRequest, _ as LocationCaptureResponse, O as LocationRequestChannel, R as LocationRequestResult, N as LocationRequestStatus, Z as LocationShareInfo, W as ResendLocationRequestRequest } from '../client-BWp5FI3x.js';
|
|
3
3
|
import { RiskProfileClient } from '../risk-profile/index.js';
|
|
4
4
|
import { E as EntityType, e as CGSConfig, R as RequestOptions, P as PaginationParams } from '../types-BpKxSXGF.js';
|
|
5
5
|
import { C as CustomerProfile } from '../types-DfHLp_tz.js';
|
package/dist/compliance/index.js
CHANGED
|
@@ -84,7 +84,7 @@ function createConsoleLogger() {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
// src/core/version.ts
|
|
87
|
-
var SDK_VERSION = "1.
|
|
87
|
+
var SDK_VERSION = "1.2.0";
|
|
88
88
|
|
|
89
89
|
// src/core/client.ts
|
|
90
90
|
var BaseClient = class {
|
|
@@ -309,6 +309,256 @@ var BaseClient = class {
|
|
|
309
309
|
}
|
|
310
310
|
};
|
|
311
311
|
|
|
312
|
+
// src/shared/browser-utils.ts
|
|
313
|
+
function generateUUID() {
|
|
314
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
315
|
+
return crypto.randomUUID();
|
|
316
|
+
}
|
|
317
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
318
|
+
const r = Math.random() * 16 | 0;
|
|
319
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
320
|
+
return v.toString(16);
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
function generateDeviceId() {
|
|
324
|
+
if (typeof window === "undefined" || typeof localStorage === "undefined") {
|
|
325
|
+
return generateUUID();
|
|
326
|
+
}
|
|
327
|
+
const storageKey = "cgs_device_id";
|
|
328
|
+
let deviceId = localStorage.getItem(storageKey);
|
|
329
|
+
if (!deviceId) {
|
|
330
|
+
deviceId = generateUUID();
|
|
331
|
+
localStorage.setItem(storageKey, deviceId);
|
|
332
|
+
}
|
|
333
|
+
return deviceId;
|
|
334
|
+
}
|
|
335
|
+
function getBrowserInfo() {
|
|
336
|
+
if (typeof navigator === "undefined") {
|
|
337
|
+
return { browser: "unknown", browser_version: "", os: "unknown", os_version: "" };
|
|
338
|
+
}
|
|
339
|
+
const ua = navigator.userAgent;
|
|
340
|
+
let browser = "unknown";
|
|
341
|
+
let browserVersion = "";
|
|
342
|
+
let os = "unknown";
|
|
343
|
+
let osVersion = "";
|
|
344
|
+
if (ua.includes("Firefox/")) {
|
|
345
|
+
browser = "Firefox";
|
|
346
|
+
browserVersion = ua.match(/Firefox\/([\d.]+)/)?.[1] || "";
|
|
347
|
+
} else if (ua.includes("Edg/")) {
|
|
348
|
+
browser = "Edge";
|
|
349
|
+
browserVersion = ua.match(/Edg\/([\d.]+)/)?.[1] || "";
|
|
350
|
+
} else if (ua.includes("Chrome/")) {
|
|
351
|
+
browser = "Chrome";
|
|
352
|
+
browserVersion = ua.match(/Chrome\/([\d.]+)/)?.[1] || "";
|
|
353
|
+
} else if (ua.includes("Safari/") && !ua.includes("Chrome")) {
|
|
354
|
+
browser = "Safari";
|
|
355
|
+
browserVersion = ua.match(/Version\/([\d.]+)/)?.[1] || "";
|
|
356
|
+
} else if (ua.includes("Opera") || ua.includes("OPR/")) {
|
|
357
|
+
browser = "Opera";
|
|
358
|
+
browserVersion = ua.match(/(?:Opera|OPR)\/([\d.]+)/)?.[1] || "";
|
|
359
|
+
}
|
|
360
|
+
if (ua.includes("Windows")) {
|
|
361
|
+
os = "Windows";
|
|
362
|
+
if (ua.includes("Windows NT 10.0")) osVersion = "10";
|
|
363
|
+
else if (ua.includes("Windows NT 6.3")) osVersion = "8.1";
|
|
364
|
+
else if (ua.includes("Windows NT 6.2")) osVersion = "8";
|
|
365
|
+
else if (ua.includes("Windows NT 6.1")) osVersion = "7";
|
|
366
|
+
} else if (ua.includes("Mac OS X")) {
|
|
367
|
+
os = "macOS";
|
|
368
|
+
osVersion = ua.match(/Mac OS X ([\d_]+)/)?.[1]?.replace(/_/g, ".") || "";
|
|
369
|
+
} else if (ua.includes("Linux")) {
|
|
370
|
+
os = "Linux";
|
|
371
|
+
} else if (ua.includes("Android")) {
|
|
372
|
+
os = "Android";
|
|
373
|
+
osVersion = ua.match(/Android ([\d.]+)/)?.[1] || "";
|
|
374
|
+
} else if (ua.includes("iOS") || ua.includes("iPhone") || ua.includes("iPad")) {
|
|
375
|
+
os = "iOS";
|
|
376
|
+
osVersion = ua.match(/OS ([\d_]+)/)?.[1]?.replace(/_/g, ".") || "";
|
|
377
|
+
}
|
|
378
|
+
return { browser, browser_version: browserVersion, os, os_version: osVersion };
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// src/geolocation/ciphertext.ts
|
|
382
|
+
var CIPHER_TEXT_EXPIRY_MINUTES = 5;
|
|
383
|
+
async function computeHMAC(key, message) {
|
|
384
|
+
if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.subtle) {
|
|
385
|
+
const encoder = new TextEncoder();
|
|
386
|
+
const keyData = encoder.encode(key);
|
|
387
|
+
const msgData = encoder.encode(message);
|
|
388
|
+
const cryptoKey = await globalThis.crypto.subtle.importKey(
|
|
389
|
+
"raw",
|
|
390
|
+
keyData,
|
|
391
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
392
|
+
false,
|
|
393
|
+
["sign"]
|
|
394
|
+
);
|
|
395
|
+
const signature = await globalThis.crypto.subtle.sign("HMAC", cryptoKey, msgData);
|
|
396
|
+
const bytes = new Uint8Array(signature);
|
|
397
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
398
|
+
}
|
|
399
|
+
const { createHmac } = await import('crypto');
|
|
400
|
+
return createHmac("sha256", key).update(message).digest("hex");
|
|
401
|
+
}
|
|
402
|
+
function getWebGLInfo() {
|
|
403
|
+
if (typeof document === "undefined") return null;
|
|
404
|
+
try {
|
|
405
|
+
const canvas = document.createElement("canvas");
|
|
406
|
+
const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
|
|
407
|
+
if (!gl) return null;
|
|
408
|
+
const debugInfo = gl.getExtension("WEBGL_debug_renderer_info");
|
|
409
|
+
if (!debugInfo) return null;
|
|
410
|
+
return {
|
|
411
|
+
vendor: gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) || "",
|
|
412
|
+
renderer: gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) || ""
|
|
413
|
+
};
|
|
414
|
+
} catch {
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function getNetworkInfo() {
|
|
419
|
+
if (typeof navigator === "undefined") return void 0;
|
|
420
|
+
const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
|
|
421
|
+
if (!connection) return void 0;
|
|
422
|
+
return {
|
|
423
|
+
effective_type: connection.effectiveType,
|
|
424
|
+
downlink: connection.downlink,
|
|
425
|
+
rtt: connection.rtt,
|
|
426
|
+
save_data: connection.saveData
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
|
|
430
|
+
if (typeof navigator === "undefined" || !navigator.geolocation) {
|
|
431
|
+
return null;
|
|
432
|
+
}
|
|
433
|
+
return new Promise((resolve) => {
|
|
434
|
+
navigator.geolocation.getCurrentPosition(
|
|
435
|
+
(position) => {
|
|
436
|
+
const { latitude, longitude, accuracy } = position.coords;
|
|
437
|
+
if (latitude < -90 || latitude > 90) {
|
|
438
|
+
resolve(null);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
if (longitude < -180 || longitude > 180) {
|
|
442
|
+
resolve(null);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
if (accuracy !== null && accuracy !== void 0 && accuracy <= 0) {
|
|
446
|
+
resolve(null);
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
resolve({
|
|
450
|
+
latitude,
|
|
451
|
+
longitude,
|
|
452
|
+
accuracy,
|
|
453
|
+
altitude: position.coords.altitude ?? void 0,
|
|
454
|
+
altitude_accuracy: position.coords.altitudeAccuracy ?? void 0,
|
|
455
|
+
heading: position.coords.heading ?? void 0,
|
|
456
|
+
speed: position.coords.speed ?? void 0,
|
|
457
|
+
timestamp: position.timestamp
|
|
458
|
+
});
|
|
459
|
+
},
|
|
460
|
+
() => {
|
|
461
|
+
resolve(null);
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
enableHighAccuracy: highAccuracy,
|
|
465
|
+
timeout,
|
|
466
|
+
maximumAge: 0
|
|
467
|
+
}
|
|
468
|
+
);
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
function collectDeviceData(includeWebGL) {
|
|
472
|
+
const browserInfo = getBrowserInfo();
|
|
473
|
+
const webglInfo = includeWebGL ? getWebGLInfo() : null;
|
|
474
|
+
return {
|
|
475
|
+
device_id: generateDeviceId(),
|
|
476
|
+
user_agent: typeof navigator !== "undefined" ? navigator.userAgent : "",
|
|
477
|
+
platform: typeof navigator !== "undefined" ? navigator.platform : "",
|
|
478
|
+
browser: browserInfo.browser,
|
|
479
|
+
browser_version: browserInfo.browser_version,
|
|
480
|
+
os: browserInfo.os,
|
|
481
|
+
os_version: browserInfo.os_version,
|
|
482
|
+
screen_resolution: typeof screen !== "undefined" ? `${screen.width}x${screen.height}` : void 0,
|
|
483
|
+
language: typeof navigator !== "undefined" ? navigator.language : void 0,
|
|
484
|
+
timezone: Intl?.DateTimeFormat?.()?.resolvedOptions?.()?.timeZone,
|
|
485
|
+
color_depth: typeof screen !== "undefined" ? screen.colorDepth : void 0,
|
|
486
|
+
hardware_concurrency: typeof navigator !== "undefined" ? navigator.hardwareConcurrency : void 0,
|
|
487
|
+
device_memory: typeof navigator !== "undefined" ? navigator.deviceMemory : void 0,
|
|
488
|
+
touch_support: typeof navigator !== "undefined" ? navigator.maxTouchPoints > 0 : void 0,
|
|
489
|
+
webgl_vendor: webglInfo?.vendor,
|
|
490
|
+
webgl_renderer: webglInfo?.renderer
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
function encodePayload(payload) {
|
|
494
|
+
const json = JSON.stringify(payload);
|
|
495
|
+
if (typeof btoa !== "undefined") {
|
|
496
|
+
return btoa(unescape(encodeURIComponent(json)));
|
|
497
|
+
} else if (typeof Buffer !== "undefined") {
|
|
498
|
+
return Buffer.from(json, "utf-8").toString("base64");
|
|
499
|
+
}
|
|
500
|
+
throw new Error("No base64 encoding method available");
|
|
501
|
+
}
|
|
502
|
+
async function generateCipherText(options, config) {
|
|
503
|
+
const warnings = [];
|
|
504
|
+
let requestLocation = options.requestLocation ?? false;
|
|
505
|
+
if (config?.require_gps) {
|
|
506
|
+
const reason = options.reason;
|
|
507
|
+
if (reason === "login" && config.require_gps.login || reason === "registration" && config.require_gps.registration || reason === "transaction" && config.require_gps.transaction) {
|
|
508
|
+
requestLocation = true;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
const deviceData = collectDeviceData(options.includeWebGL !== false);
|
|
512
|
+
let locationData;
|
|
513
|
+
if (requestLocation) {
|
|
514
|
+
const location = await requestGPSLocation(
|
|
515
|
+
options.locationTimeout || 1e4,
|
|
516
|
+
options.highAccuracy !== false
|
|
517
|
+
);
|
|
518
|
+
if (location) {
|
|
519
|
+
locationData = location;
|
|
520
|
+
} else {
|
|
521
|
+
warnings.push("GPS location not available or permission denied");
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
let networkData;
|
|
525
|
+
if (options.includeNetworkInfo !== false) {
|
|
526
|
+
networkData = getNetworkInfo();
|
|
527
|
+
}
|
|
528
|
+
const now = /* @__PURE__ */ new Date();
|
|
529
|
+
const expiry = new Date(now.getTime() + CIPHER_TEXT_EXPIRY_MINUTES * 60 * 1e3);
|
|
530
|
+
const payload = {
|
|
531
|
+
device: deviceData,
|
|
532
|
+
location: locationData,
|
|
533
|
+
network: networkData,
|
|
534
|
+
metadata: {
|
|
535
|
+
collected_at: now.toISOString(),
|
|
536
|
+
sdk_version: SDK_VERSION,
|
|
537
|
+
collection_reason: options.reason,
|
|
538
|
+
page_url: typeof window !== "undefined" ? window.location.href : void 0,
|
|
539
|
+
referrer: typeof document !== "undefined" ? document.referrer || void 0 : void 0
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
const encoded = encodePayload(payload);
|
|
543
|
+
const timestamp = now.getTime().toString(36);
|
|
544
|
+
let cipherText;
|
|
545
|
+
const hmacKey = options.signingKey || options.apiKey;
|
|
546
|
+
if (hmacKey) {
|
|
547
|
+
const message = `02.${timestamp}.${encoded}`;
|
|
548
|
+
const hmac = await computeHMAC(hmacKey, message);
|
|
549
|
+
cipherText = `${message}.${hmac}`;
|
|
550
|
+
} else {
|
|
551
|
+
cipherText = `01.${timestamp}.${encoded}`;
|
|
552
|
+
}
|
|
553
|
+
return {
|
|
554
|
+
cipherText,
|
|
555
|
+
locationCaptured: !!locationData,
|
|
556
|
+
warnings: warnings.length > 0 ? warnings : void 0,
|
|
557
|
+
generatedAt: now.toISOString(),
|
|
558
|
+
expiresAt: expiry.toISOString()
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
|
|
312
562
|
// src/geolocation/client.ts
|
|
313
563
|
var GeolocationClient = class extends BaseClient {
|
|
314
564
|
constructor(config) {
|
|
@@ -409,7 +659,11 @@ var GeolocationClient = class extends BaseClient {
|
|
|
409
659
|
* ```
|
|
410
660
|
*/
|
|
411
661
|
async getGPSConfig(requestOptions) {
|
|
412
|
-
|
|
662
|
+
const config = await this.requestWithRetry("/api/v1/geo/config", void 0, void 0, void 0, requestOptions);
|
|
663
|
+
if (config.signing_key) {
|
|
664
|
+
this.cachedSigningKey = config.signing_key;
|
|
665
|
+
}
|
|
666
|
+
return config;
|
|
413
667
|
}
|
|
414
668
|
// ============================================================================
|
|
415
669
|
// CipherText Validation
|
|
@@ -669,6 +923,36 @@ var GeolocationClient = class extends BaseClient {
|
|
|
669
923
|
}, void 0, requestOptions);
|
|
670
924
|
}
|
|
671
925
|
// ============================================================================
|
|
926
|
+
// CipherText Generation
|
|
927
|
+
// ============================================================================
|
|
928
|
+
/**
|
|
929
|
+
* Generate a signed cipherText containing device and location data.
|
|
930
|
+
*
|
|
931
|
+
* Automatically passes the client's API key for HMAC signing (v02 format).
|
|
932
|
+
* If no API key is configured, falls back to unsigned v01 format.
|
|
933
|
+
*
|
|
934
|
+
* @param options - Options for cipherText generation
|
|
935
|
+
* @param gpsConfig - Optional GPS config (from getGPSConfig)
|
|
936
|
+
* @returns CipherText result with the signed string
|
|
937
|
+
*
|
|
938
|
+
* @example
|
|
939
|
+
* ```typescript
|
|
940
|
+
* const result = await client.generateCipherText({ reason: 'login' });
|
|
941
|
+
* console.log(result.cipherText); // v02 signed cipherText
|
|
942
|
+
* ```
|
|
943
|
+
*/
|
|
944
|
+
async generateCipherText(options, gpsConfig) {
|
|
945
|
+
let signingKey = this.cachedSigningKey;
|
|
946
|
+
if (!signingKey) {
|
|
947
|
+
const config = await this.getGPSConfig();
|
|
948
|
+
signingKey = config.signing_key;
|
|
949
|
+
}
|
|
950
|
+
return generateCipherText(
|
|
951
|
+
{ ...options, signingKey: signingKey || void 0 },
|
|
952
|
+
gpsConfig
|
|
953
|
+
);
|
|
954
|
+
}
|
|
955
|
+
// ============================================================================
|
|
672
956
|
// Utility Methods (inherited from BaseClient: healthCheck, updateConfig, getConfig, buildQueryString)
|
|
673
957
|
// ============================================================================
|
|
674
958
|
};
|