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
|
@@ -73,6 +73,19 @@ var sdkReasons = {
|
|
|
73
73
|
})
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
+
// src/core/auth.ts
|
|
77
|
+
var StaticApiKeyProvider = class {
|
|
78
|
+
constructor(apiKey) {
|
|
79
|
+
this.apiKey = apiKey;
|
|
80
|
+
}
|
|
81
|
+
async getCredential() {
|
|
82
|
+
return this.apiKey ? { scheme: "Bearer", token: this.apiKey } : null;
|
|
83
|
+
}
|
|
84
|
+
canRefresh() {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
76
89
|
// src/core/errors.ts
|
|
77
90
|
var VesantError = class _VesantError extends Error {
|
|
78
91
|
constructor(message, code, statusCode, details) {
|
|
@@ -379,6 +392,12 @@ var BaseClient = class {
|
|
|
379
392
|
if (!config.tenantId?.trim()) {
|
|
380
393
|
throw new ValidationError("tenantId is required and must be a non-empty string", ["tenantId"]);
|
|
381
394
|
}
|
|
395
|
+
if (typeof fetch === "undefined") {
|
|
396
|
+
throw new VesantError(
|
|
397
|
+
"The Vesant SDK requires a global fetch (Node.js >= 18). Upgrade Node or provide a fetch polyfill.",
|
|
398
|
+
"RUNTIME_UNSUPPORTED"
|
|
399
|
+
);
|
|
400
|
+
}
|
|
382
401
|
this.interceptors = config.interceptors || [];
|
|
383
402
|
this.logger = config.logger || createConsoleLogger();
|
|
384
403
|
let environment = config.environment;
|
|
@@ -397,11 +416,12 @@ var BaseClient = class {
|
|
|
397
416
|
environment,
|
|
398
417
|
headers: config.headers || {},
|
|
399
418
|
timeout: config.timeout || 1e4,
|
|
400
|
-
retries: config.retries
|
|
419
|
+
retries: config.retries ?? 3,
|
|
401
420
|
debug: config.debug || false,
|
|
402
421
|
interceptors: this.interceptors,
|
|
403
422
|
logger: this.logger
|
|
404
423
|
};
|
|
424
|
+
this.authProvider = config.authProvider ?? (apiKey ? new StaticApiKeyProvider(apiKey) : void 0);
|
|
405
425
|
if (config.circuitBreaker) {
|
|
406
426
|
this.circuitBreaker = new CircuitBreaker(config.circuitBreaker);
|
|
407
427
|
}
|
|
@@ -447,8 +467,12 @@ var BaseClient = class {
|
|
|
447
467
|
...this.config.headers,
|
|
448
468
|
...options.headers || {}
|
|
449
469
|
};
|
|
450
|
-
|
|
451
|
-
|
|
470
|
+
const credential = await this.authProvider?.getCredential({
|
|
471
|
+
tenantId: this.config.tenantId,
|
|
472
|
+
requestId
|
|
473
|
+
});
|
|
474
|
+
if (credential) {
|
|
475
|
+
headers["Authorization"] = `${credential.scheme ?? "Bearer"} ${credential.token}`;
|
|
452
476
|
}
|
|
453
477
|
if (this.config.environment === "sandbox") {
|
|
454
478
|
headers["X-Sandbox"] = "true";
|
|
@@ -477,10 +501,28 @@ var BaseClient = class {
|
|
|
477
501
|
if (this.config.debug) {
|
|
478
502
|
this.logger.debug(`${finalOptions.method || "GET"} ${endpoint}`);
|
|
479
503
|
}
|
|
480
|
-
|
|
504
|
+
let response = await fetch(url, {
|
|
481
505
|
...finalOptions,
|
|
482
506
|
signal: controller.signal
|
|
483
507
|
});
|
|
508
|
+
if (response.status === 401 && this.authProvider?.canRefresh?.()) {
|
|
509
|
+
const refreshed = await this.authProvider.getCredential({
|
|
510
|
+
tenantId: this.config.tenantId,
|
|
511
|
+
requestId,
|
|
512
|
+
forceRefresh: true
|
|
513
|
+
});
|
|
514
|
+
if (refreshed) {
|
|
515
|
+
this.config.onCredentialRotated?.({ reason: "unauthorized" });
|
|
516
|
+
finalOptions = {
|
|
517
|
+
...finalOptions,
|
|
518
|
+
headers: {
|
|
519
|
+
...finalOptions.headers,
|
|
520
|
+
Authorization: `${refreshed.scheme ?? "Bearer"} ${refreshed.token}`
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
response = await fetch(url, { ...finalOptions, signal: controller.signal });
|
|
524
|
+
}
|
|
525
|
+
}
|
|
484
526
|
clearTimeout(timeoutId);
|
|
485
527
|
if (this.rateLimitTracker) {
|
|
486
528
|
this.rateLimitTracker.updateFromHeaders(response.headers);
|
|
@@ -670,6 +712,9 @@ var BaseClient = class {
|
|
|
670
712
|
if (config.interceptors) {
|
|
671
713
|
this.interceptors = config.interceptors;
|
|
672
714
|
}
|
|
715
|
+
if (config.authProvider !== void 0 || config.apiKey !== void 0) {
|
|
716
|
+
this.authProvider = this.config.authProvider ?? (this.config.apiKey ? new StaticApiKeyProvider(this.config.apiKey) : void 0);
|
|
717
|
+
}
|
|
673
718
|
}
|
|
674
719
|
/**
|
|
675
720
|
* Get current configuration (readonly)
|
|
@@ -697,6 +742,61 @@ var BaseClient = class {
|
|
|
697
742
|
}
|
|
698
743
|
};
|
|
699
744
|
|
|
745
|
+
// src/geolocation/integrity.ts
|
|
746
|
+
var isNil = (v) => v === null || v === void 0;
|
|
747
|
+
function assessGpsIntegrity(input, opts = {}) {
|
|
748
|
+
const flags = [];
|
|
749
|
+
const now = opts.now ?? (() => Date.now());
|
|
750
|
+
const maxAgeMs = opts.maxAgeMs ?? 6e4;
|
|
751
|
+
const minAccuracy = opts.minAccuracyMeters ?? 1;
|
|
752
|
+
const { accuracy, altitude, altitudeAccuracy, heading, speed, timestamp } = input;
|
|
753
|
+
if (isNil(accuracy)) {
|
|
754
|
+
flags.push("accuracy_missing");
|
|
755
|
+
} else if (accuracy === 0) {
|
|
756
|
+
flags.push("accuracy_zero");
|
|
757
|
+
} else if (accuracy < minAccuracy) {
|
|
758
|
+
flags.push("accuracy_implausibly_small");
|
|
759
|
+
}
|
|
760
|
+
const hasMotion = !isNil(heading) || !isNil(speed);
|
|
761
|
+
if (hasMotion && (isNil(accuracy) || accuracy === 0)) {
|
|
762
|
+
flags.push("motion_without_accuracy");
|
|
763
|
+
}
|
|
764
|
+
if (!isNil(altitude) && isNil(altitudeAccuracy)) {
|
|
765
|
+
flags.push("altitude_without_accuracy");
|
|
766
|
+
}
|
|
767
|
+
if (timestamp !== void 0 && now() - timestamp > maxAgeMs) {
|
|
768
|
+
flags.push("stale_timestamp");
|
|
769
|
+
}
|
|
770
|
+
if (opts.permissionState === "denied" || opts.permissionState === "prompt") {
|
|
771
|
+
flags.push(`permission_${opts.permissionState}`);
|
|
772
|
+
}
|
|
773
|
+
return { suspicious: flags.length > 0, flags };
|
|
774
|
+
}
|
|
775
|
+
function gpsIntegrityInputFromPosition(position) {
|
|
776
|
+
const c = position.coords;
|
|
777
|
+
return {
|
|
778
|
+
latitude: c.latitude,
|
|
779
|
+
longitude: c.longitude,
|
|
780
|
+
accuracy: c.accuracy,
|
|
781
|
+
altitude: c.altitude,
|
|
782
|
+
altitudeAccuracy: c.altitudeAccuracy,
|
|
783
|
+
heading: c.heading,
|
|
784
|
+
speed: c.speed,
|
|
785
|
+
timestamp: position.timestamp
|
|
786
|
+
};
|
|
787
|
+
}
|
|
788
|
+
async function probeGeolocationPermission() {
|
|
789
|
+
try {
|
|
790
|
+
if (typeof navigator === "undefined" || !navigator.permissions?.query) {
|
|
791
|
+
return "unavailable";
|
|
792
|
+
}
|
|
793
|
+
const status = await navigator.permissions.query({ name: "geolocation" });
|
|
794
|
+
return status.state;
|
|
795
|
+
} catch {
|
|
796
|
+
return "unavailable";
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
|
|
700
800
|
// src/geolocation/ciphertext.ts
|
|
701
801
|
var CIPHER_TEXT_EXPIRY_MINUTES = 5;
|
|
702
802
|
async function computeHMAC(key, message) {
|
|
@@ -749,6 +849,7 @@ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
|
|
|
749
849
|
if (typeof navigator === "undefined" || !navigator.geolocation) {
|
|
750
850
|
return null;
|
|
751
851
|
}
|
|
852
|
+
const permissionState = await probeGeolocationPermission();
|
|
752
853
|
return new Promise((resolve) => {
|
|
753
854
|
navigator.geolocation.getCurrentPosition(
|
|
754
855
|
(position) => {
|
|
@@ -765,6 +866,7 @@ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
|
|
|
765
866
|
resolve(null);
|
|
766
867
|
return;
|
|
767
868
|
}
|
|
869
|
+
const { flags } = assessGpsIntegrity(gpsIntegrityInputFromPosition(position), { permissionState });
|
|
768
870
|
resolve({
|
|
769
871
|
latitude,
|
|
770
872
|
longitude,
|
|
@@ -773,7 +875,8 @@ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
|
|
|
773
875
|
altitude_accuracy: position.coords.altitudeAccuracy ?? void 0,
|
|
774
876
|
heading: position.coords.heading ?? void 0,
|
|
775
877
|
speed: position.coords.speed ?? void 0,
|
|
776
|
-
timestamp: position.timestamp
|
|
878
|
+
timestamp: position.timestamp,
|
|
879
|
+
integrity_flags: flags.length ? flags : void 0
|
|
777
880
|
});
|
|
778
881
|
},
|
|
779
882
|
() => {
|
|
@@ -840,6 +943,9 @@ async function generateCipherText(options, config) {
|
|
|
840
943
|
);
|
|
841
944
|
if (location) {
|
|
842
945
|
locationData = location;
|
|
946
|
+
if (location.integrity_flags?.length) {
|
|
947
|
+
warnings.push(`GPS integrity flags (advisory): ${location.integrity_flags.join(", ")}`);
|
|
948
|
+
}
|
|
843
949
|
} else if (gpsRequiredByConfig) {
|
|
844
950
|
throw new VesantError(
|
|
845
951
|
`GPS location is required for ${options.reason} by tenant configuration, but GPS was not available or permission was denied`,
|
|
@@ -934,8 +1040,8 @@ var GeolocationClient = class extends BaseClient {
|
|
|
934
1040
|
* ```
|
|
935
1041
|
*/
|
|
936
1042
|
async verifyIP(request, requestOptions) {
|
|
937
|
-
if (!request.ip_address
|
|
938
|
-
throw new ValidationError("ip_address
|
|
1043
|
+
if (request.ip_address !== void 0 && !request.ip_address.trim()) {
|
|
1044
|
+
throw new ValidationError("ip_address, when provided, must be a non-empty string", ["ip_address"]);
|
|
939
1045
|
}
|
|
940
1046
|
return this.requestWithRetry("/api/v1/geo/verify", {
|
|
941
1047
|
method: "POST",
|
|
@@ -1285,20 +1391,12 @@ var GeolocationClient = class extends BaseClient {
|
|
|
1285
1391
|
*
|
|
1286
1392
|
* @example
|
|
1287
1393
|
* ```typescript
|
|
1288
|
-
* //
|
|
1394
|
+
* // GPS (the web SDK is GPS + IP only; the server handles the IP fallback)
|
|
1289
1395
|
* const result = await client.captureLocation(token, {
|
|
1290
1396
|
* latitude: 37.7749,
|
|
1291
1397
|
* longitude: -122.4194,
|
|
1292
1398
|
* accuracy: 10
|
|
1293
1399
|
* });
|
|
1294
|
-
*
|
|
1295
|
-
* // Using WiFi positioning (fallback)
|
|
1296
|
-
* const result = await client.captureLocation(token, {
|
|
1297
|
-
* wifi_networks: [
|
|
1298
|
-
* { macAddress: "00:11:22:33:44:55", signalStrength: -50 },
|
|
1299
|
-
* { macAddress: "AA:BB:CC:DD:EE:FF", signalStrength: -70 }
|
|
1300
|
-
* ]
|
|
1301
|
-
* });
|
|
1302
1400
|
* ```
|
|
1303
1401
|
*/
|
|
1304
1402
|
async captureLocation(token, capture, requestOptions) {
|