vesant-sdk 1.7.0-dev.b2c9ecf → 1.7.0-dev.b4284ca
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-B32yBt1b.d.ts → client-0NOPDnT0.d.ts} +16 -26
- package/dist/{client-BqPVh5jH.d.mts → client-CvWNRwwg.d.mts} +16 -26
- package/dist/{client-CHPEgasE.d.mts → client-Dps40EtF.d.mts} +2 -2
- package/dist/{client-pKE_gii_.d.ts → client-SMxqod4j.d.ts} +2 -2
- package/dist/{client-6sSaxufk.d.mts → client-q9fN8Hhf.d.mts} +96 -1
- package/dist/{client-6sSaxufk.d.ts → client-q9fN8Hhf.d.ts} +96 -1
- package/dist/compliance/index.d.mts +3 -3
- package/dist/compliance/index.d.ts +3 -3
- package/dist/compliance/index.js +114 -16
- package/dist/compliance/index.js.map +1 -1
- package/dist/compliance/index.mjs +114 -16
- package/dist/compliance/index.mjs.map +1 -1
- package/dist/decisions/index.d.mts +1 -1
- package/dist/decisions/index.d.ts +1 -1
- package/dist/decisions/index.js +49 -4
- package/dist/decisions/index.js.map +1 -1
- package/dist/decisions/index.mjs +49 -4
- package/dist/decisions/index.mjs.map +1 -1
- package/dist/geolocation/index.d.mts +59 -4
- package/dist/geolocation/index.d.ts +59 -4
- package/dist/geolocation/index.js +117 -16
- package/dist/geolocation/index.js.map +1 -1
- package/dist/geolocation/index.mjs +115 -17
- package/dist/geolocation/index.mjs.map +1 -1
- package/dist/index-CPOrMRaH.d.ts +264 -0
- package/dist/index-CimDmgZb.d.mts +264 -0
- package/dist/index.d.mts +25 -8
- package/dist/index.d.ts +25 -8
- package/dist/index.js +274 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +267 -38
- package/dist/index.mjs.map +1 -1
- package/dist/kyc/core.d.mts +1 -1
- package/dist/kyc/core.d.ts +1 -1
- package/dist/kyc/core.js +49 -4
- package/dist/kyc/core.js.map +1 -1
- package/dist/kyc/core.mjs +49 -4
- package/dist/kyc/core.mjs.map +1 -1
- package/dist/kyc/index.d.mts +1 -1
- package/dist/kyc/index.d.ts +1 -1
- package/dist/kyc/index.js +49 -4
- package/dist/kyc/index.js.map +1 -1
- package/dist/kyc/index.mjs +49 -4
- package/dist/kyc/index.mjs.map +1 -1
- package/dist/react.d.mts +7 -3
- package/dist/react.d.ts +7 -3
- package/dist/react.js +68 -4
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +68 -4
- package/dist/react.mjs.map +1 -1
- package/dist/risk-profile/index.d.mts +1 -1
- package/dist/risk-profile/index.d.ts +1 -1
- package/dist/risk-profile/index.js +49 -4
- package/dist/risk-profile/index.js.map +1 -1
- package/dist/risk-profile/index.mjs +49 -4
- package/dist/risk-profile/index.mjs.map +1 -1
- package/dist/scores/index.d.mts +1 -1
- package/dist/scores/index.d.ts +1 -1
- package/dist/scores/index.js +49 -4
- package/dist/scores/index.js.map +1 -1
- package/dist/scores/index.mjs +49 -4
- package/dist/scores/index.mjs.map +1 -1
- package/dist/tax/index.d.mts +1 -1
- package/dist/tax/index.d.ts +1 -1
- package/dist/tax/index.js +49 -4
- package/dist/tax/index.js.map +1 -1
- package/dist/tax/index.mjs +49 -4
- package/dist/tax/index.mjs.map +1 -1
- package/dist/webhooks/index.d.mts +2 -189
- package/dist/webhooks/index.d.ts +2 -189
- package/dist/webhooks/index.js +85 -21
- package/dist/webhooks/index.js.map +1 -1
- package/dist/webhooks/index.mjs +85 -22
- package/dist/webhooks/index.mjs.map +1 -1
- package/package.json +4 -1
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
// src/core/auth.ts
|
|
4
|
+
var StaticApiKeyProvider = class {
|
|
5
|
+
constructor(apiKey) {
|
|
6
|
+
this.apiKey = apiKey;
|
|
7
|
+
}
|
|
8
|
+
async getCredential() {
|
|
9
|
+
return this.apiKey ? { scheme: "Bearer", token: this.apiKey } : null;
|
|
10
|
+
}
|
|
11
|
+
canRefresh() {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
3
16
|
// src/core/errors.ts
|
|
4
17
|
var VesantError = class _VesantError extends Error {
|
|
5
18
|
constructor(message, code, statusCode, details) {
|
|
@@ -298,6 +311,12 @@ var BaseClient = class {
|
|
|
298
311
|
if (!config.tenantId?.trim()) {
|
|
299
312
|
throw new ValidationError("tenantId is required and must be a non-empty string", ["tenantId"]);
|
|
300
313
|
}
|
|
314
|
+
if (typeof fetch === "undefined") {
|
|
315
|
+
throw new VesantError(
|
|
316
|
+
"The Vesant SDK requires a global fetch (Node.js >= 18). Upgrade Node or provide a fetch polyfill.",
|
|
317
|
+
"RUNTIME_UNSUPPORTED"
|
|
318
|
+
);
|
|
319
|
+
}
|
|
301
320
|
this.interceptors = config.interceptors || [];
|
|
302
321
|
this.logger = config.logger || createConsoleLogger();
|
|
303
322
|
let environment = config.environment;
|
|
@@ -316,11 +335,12 @@ var BaseClient = class {
|
|
|
316
335
|
environment,
|
|
317
336
|
headers: config.headers || {},
|
|
318
337
|
timeout: config.timeout || 1e4,
|
|
319
|
-
retries: config.retries
|
|
338
|
+
retries: config.retries ?? 3,
|
|
320
339
|
debug: config.debug || false,
|
|
321
340
|
interceptors: this.interceptors,
|
|
322
341
|
logger: this.logger
|
|
323
342
|
};
|
|
343
|
+
this.authProvider = config.authProvider ?? (apiKey ? new StaticApiKeyProvider(apiKey) : void 0);
|
|
324
344
|
if (config.circuitBreaker) {
|
|
325
345
|
this.circuitBreaker = new CircuitBreaker(config.circuitBreaker);
|
|
326
346
|
}
|
|
@@ -366,8 +386,12 @@ var BaseClient = class {
|
|
|
366
386
|
...this.config.headers,
|
|
367
387
|
...options.headers || {}
|
|
368
388
|
};
|
|
369
|
-
|
|
370
|
-
|
|
389
|
+
const credential = await this.authProvider?.getCredential({
|
|
390
|
+
tenantId: this.config.tenantId,
|
|
391
|
+
requestId
|
|
392
|
+
});
|
|
393
|
+
if (credential) {
|
|
394
|
+
headers["Authorization"] = `${credential.scheme ?? "Bearer"} ${credential.token}`;
|
|
371
395
|
}
|
|
372
396
|
if (this.config.environment === "sandbox") {
|
|
373
397
|
headers["X-Sandbox"] = "true";
|
|
@@ -396,10 +420,28 @@ var BaseClient = class {
|
|
|
396
420
|
if (this.config.debug) {
|
|
397
421
|
this.logger.debug(`${finalOptions.method || "GET"} ${endpoint}`);
|
|
398
422
|
}
|
|
399
|
-
|
|
423
|
+
let response = await fetch(url, {
|
|
400
424
|
...finalOptions,
|
|
401
425
|
signal: controller.signal
|
|
402
426
|
});
|
|
427
|
+
if (response.status === 401 && this.authProvider?.canRefresh?.()) {
|
|
428
|
+
const refreshed = await this.authProvider.getCredential({
|
|
429
|
+
tenantId: this.config.tenantId,
|
|
430
|
+
requestId,
|
|
431
|
+
forceRefresh: true
|
|
432
|
+
});
|
|
433
|
+
if (refreshed) {
|
|
434
|
+
this.config.onCredentialRotated?.({ reason: "unauthorized" });
|
|
435
|
+
finalOptions = {
|
|
436
|
+
...finalOptions,
|
|
437
|
+
headers: {
|
|
438
|
+
...finalOptions.headers,
|
|
439
|
+
Authorization: `${refreshed.scheme ?? "Bearer"} ${refreshed.token}`
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
response = await fetch(url, { ...finalOptions, signal: controller.signal });
|
|
443
|
+
}
|
|
444
|
+
}
|
|
403
445
|
clearTimeout(timeoutId);
|
|
404
446
|
if (this.rateLimitTracker) {
|
|
405
447
|
this.rateLimitTracker.updateFromHeaders(response.headers);
|
|
@@ -589,6 +631,9 @@ var BaseClient = class {
|
|
|
589
631
|
if (config.interceptors) {
|
|
590
632
|
this.interceptors = config.interceptors;
|
|
591
633
|
}
|
|
634
|
+
if (config.authProvider !== void 0 || config.apiKey !== void 0) {
|
|
635
|
+
this.authProvider = this.config.authProvider ?? (this.config.apiKey ? new StaticApiKeyProvider(this.config.apiKey) : void 0);
|
|
636
|
+
}
|
|
592
637
|
}
|
|
593
638
|
/**
|
|
594
639
|
* Get current configuration (readonly)
|
|
@@ -616,6 +661,61 @@ var BaseClient = class {
|
|
|
616
661
|
}
|
|
617
662
|
};
|
|
618
663
|
|
|
664
|
+
// src/geolocation/integrity.ts
|
|
665
|
+
var isNil = (v) => v === null || v === void 0;
|
|
666
|
+
function assessGpsIntegrity(input, opts = {}) {
|
|
667
|
+
const flags = [];
|
|
668
|
+
const now = opts.now ?? (() => Date.now());
|
|
669
|
+
const maxAgeMs = opts.maxAgeMs ?? 6e4;
|
|
670
|
+
const minAccuracy = opts.minAccuracyMeters ?? 1;
|
|
671
|
+
const { accuracy, altitude, altitudeAccuracy, heading, speed, timestamp } = input;
|
|
672
|
+
if (isNil(accuracy)) {
|
|
673
|
+
flags.push("accuracy_missing");
|
|
674
|
+
} else if (accuracy === 0) {
|
|
675
|
+
flags.push("accuracy_zero");
|
|
676
|
+
} else if (accuracy < minAccuracy) {
|
|
677
|
+
flags.push("accuracy_implausibly_small");
|
|
678
|
+
}
|
|
679
|
+
const hasMotion = !isNil(heading) || !isNil(speed);
|
|
680
|
+
if (hasMotion && (isNil(accuracy) || accuracy === 0)) {
|
|
681
|
+
flags.push("motion_without_accuracy");
|
|
682
|
+
}
|
|
683
|
+
if (!isNil(altitude) && isNil(altitudeAccuracy)) {
|
|
684
|
+
flags.push("altitude_without_accuracy");
|
|
685
|
+
}
|
|
686
|
+
if (timestamp !== void 0 && now() - timestamp > maxAgeMs) {
|
|
687
|
+
flags.push("stale_timestamp");
|
|
688
|
+
}
|
|
689
|
+
if (opts.permissionState === "denied" || opts.permissionState === "prompt") {
|
|
690
|
+
flags.push(`permission_${opts.permissionState}`);
|
|
691
|
+
}
|
|
692
|
+
return { suspicious: flags.length > 0, flags };
|
|
693
|
+
}
|
|
694
|
+
function gpsIntegrityInputFromPosition(position) {
|
|
695
|
+
const c = position.coords;
|
|
696
|
+
return {
|
|
697
|
+
latitude: c.latitude,
|
|
698
|
+
longitude: c.longitude,
|
|
699
|
+
accuracy: c.accuracy,
|
|
700
|
+
altitude: c.altitude,
|
|
701
|
+
altitudeAccuracy: c.altitudeAccuracy,
|
|
702
|
+
heading: c.heading,
|
|
703
|
+
speed: c.speed,
|
|
704
|
+
timestamp: position.timestamp
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
async function probeGeolocationPermission() {
|
|
708
|
+
try {
|
|
709
|
+
if (typeof navigator === "undefined" || !navigator.permissions?.query) {
|
|
710
|
+
return "unavailable";
|
|
711
|
+
}
|
|
712
|
+
const status = await navigator.permissions.query({ name: "geolocation" });
|
|
713
|
+
return status.state;
|
|
714
|
+
} catch {
|
|
715
|
+
return "unavailable";
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
619
719
|
// src/geolocation/ciphertext.ts
|
|
620
720
|
var CIPHER_TEXT_EXPIRY_MINUTES = 5;
|
|
621
721
|
async function computeHMAC(key, message) {
|
|
@@ -668,6 +768,7 @@ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
|
|
|
668
768
|
if (typeof navigator === "undefined" || !navigator.geolocation) {
|
|
669
769
|
return null;
|
|
670
770
|
}
|
|
771
|
+
const permissionState = await probeGeolocationPermission();
|
|
671
772
|
return new Promise((resolve) => {
|
|
672
773
|
navigator.geolocation.getCurrentPosition(
|
|
673
774
|
(position) => {
|
|
@@ -684,6 +785,7 @@ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
|
|
|
684
785
|
resolve(null);
|
|
685
786
|
return;
|
|
686
787
|
}
|
|
788
|
+
const { flags } = assessGpsIntegrity(gpsIntegrityInputFromPosition(position), { permissionState });
|
|
687
789
|
resolve({
|
|
688
790
|
latitude,
|
|
689
791
|
longitude,
|
|
@@ -692,7 +794,8 @@ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
|
|
|
692
794
|
altitude_accuracy: position.coords.altitudeAccuracy ?? void 0,
|
|
693
795
|
heading: position.coords.heading ?? void 0,
|
|
694
796
|
speed: position.coords.speed ?? void 0,
|
|
695
|
-
timestamp: position.timestamp
|
|
797
|
+
timestamp: position.timestamp,
|
|
798
|
+
integrity_flags: flags.length ? flags : void 0
|
|
696
799
|
});
|
|
697
800
|
},
|
|
698
801
|
() => {
|
|
@@ -759,6 +862,9 @@ async function generateCipherText(options, config) {
|
|
|
759
862
|
);
|
|
760
863
|
if (location) {
|
|
761
864
|
locationData = location;
|
|
865
|
+
if (location.integrity_flags?.length) {
|
|
866
|
+
warnings.push(`GPS integrity flags (advisory): ${location.integrity_flags.join(", ")}`);
|
|
867
|
+
}
|
|
762
868
|
} else if (gpsRequiredByConfig) {
|
|
763
869
|
throw new VesantError(
|
|
764
870
|
`GPS location is required for ${options.reason} by tenant configuration, but GPS was not available or permission was denied`,
|
|
@@ -878,8 +984,8 @@ var GeolocationClient = class extends BaseClient {
|
|
|
878
984
|
* ```
|
|
879
985
|
*/
|
|
880
986
|
async verifyIP(request, requestOptions) {
|
|
881
|
-
if (!request.ip_address
|
|
882
|
-
throw new ValidationError("ip_address
|
|
987
|
+
if (request.ip_address !== void 0 && !request.ip_address.trim()) {
|
|
988
|
+
throw new ValidationError("ip_address, when provided, must be a non-empty string", ["ip_address"]);
|
|
883
989
|
}
|
|
884
990
|
return this.requestWithRetry("/api/v1/geo/verify", {
|
|
885
991
|
method: "POST",
|
|
@@ -1229,20 +1335,12 @@ var GeolocationClient = class extends BaseClient {
|
|
|
1229
1335
|
*
|
|
1230
1336
|
* @example
|
|
1231
1337
|
* ```typescript
|
|
1232
|
-
* //
|
|
1338
|
+
* // GPS (the web SDK is GPS + IP only; the server handles the IP fallback)
|
|
1233
1339
|
* const result = await client.captureLocation(token, {
|
|
1234
1340
|
* latitude: 37.7749,
|
|
1235
1341
|
* longitude: -122.4194,
|
|
1236
1342
|
* accuracy: 10
|
|
1237
1343
|
* });
|
|
1238
|
-
*
|
|
1239
|
-
* // Using WiFi positioning (fallback)
|
|
1240
|
-
* const result = await client.captureLocation(token, {
|
|
1241
|
-
* wifi_networks: [
|
|
1242
|
-
* { macAddress: "00:11:22:33:44:55", signalStrength: -50 },
|
|
1243
|
-
* { macAddress: "AA:BB:CC:DD:EE:FF", signalStrength: -70 }
|
|
1244
|
-
* ]
|
|
1245
|
-
* });
|
|
1246
1344
|
* ```
|
|
1247
1345
|
*/
|
|
1248
1346
|
async captureLocation(token, capture, requestOptions) {
|
|
@@ -1290,8 +1388,11 @@ var GeolocationClient = class extends BaseClient {
|
|
|
1290
1388
|
};
|
|
1291
1389
|
|
|
1292
1390
|
exports.GeolocationClient = GeolocationClient;
|
|
1391
|
+
exports.assessGpsIntegrity = assessGpsIntegrity;
|
|
1293
1392
|
exports.decodeCipherText = decodeCipherText;
|
|
1294
1393
|
exports.generateCipherText = generateCipherText;
|
|
1394
|
+
exports.gpsIntegrityInputFromPosition = gpsIntegrityInputFromPosition;
|
|
1295
1395
|
exports.isCipherTextExpired = isCipherTextExpired;
|
|
1396
|
+
exports.probeGeolocationPermission = probeGeolocationPermission;
|
|
1296
1397
|
//# sourceMappingURL=index.js.map
|
|
1297
1398
|
//# sourceMappingURL=index.js.map
|