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