vesant-sdk 1.7.0-dev.6f300f7 → 1.7.0-dev.6f4bf05

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.
Files changed (61) hide show
  1. package/dist/{client-D9JZgN3X.d.ts → client-0NOPDnT0.d.ts} +15 -25
  2. package/dist/{client-BG8KtVMc.d.mts → client-CvWNRwwg.d.mts} +15 -25
  3. package/dist/{client-CRZea-eJ.d.mts → client-Dps40EtF.d.mts} +1 -1
  4. package/dist/{client-749WqhDT.d.ts → client-SMxqod4j.d.ts} +1 -1
  5. package/dist/compliance/index.d.mts +2 -2
  6. package/dist/compliance/index.d.ts +2 -2
  7. package/dist/compliance/index.js +71 -12
  8. package/dist/compliance/index.js.map +1 -1
  9. package/dist/compliance/index.mjs +71 -12
  10. package/dist/compliance/index.mjs.map +1 -1
  11. package/dist/decisions/index.js +6 -0
  12. package/dist/decisions/index.js.map +1 -1
  13. package/dist/decisions/index.mjs +6 -0
  14. package/dist/decisions/index.mjs.map +1 -1
  15. package/dist/geolocation/index.d.mts +58 -3
  16. package/dist/geolocation/index.d.ts +58 -3
  17. package/dist/geolocation/index.js +74 -12
  18. package/dist/geolocation/index.js.map +1 -1
  19. package/dist/geolocation/index.mjs +72 -13
  20. package/dist/geolocation/index.mjs.map +1 -1
  21. package/dist/index-CPOrMRaH.d.ts +264 -0
  22. package/dist/index-CimDmgZb.d.mts +264 -0
  23. package/dist/index.d.mts +23 -6
  24. package/dist/index.d.ts +23 -6
  25. package/dist/index.js +186 -33
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +181 -34
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/kyc/core.js +6 -0
  30. package/dist/kyc/core.js.map +1 -1
  31. package/dist/kyc/core.mjs +6 -0
  32. package/dist/kyc/core.mjs.map +1 -1
  33. package/dist/kyc/index.js +6 -0
  34. package/dist/kyc/index.js.map +1 -1
  35. package/dist/kyc/index.mjs +6 -0
  36. package/dist/kyc/index.mjs.map +1 -1
  37. package/dist/react.d.mts +6 -2
  38. package/dist/react.d.ts +6 -2
  39. package/dist/react.js +68 -4
  40. package/dist/react.js.map +1 -1
  41. package/dist/react.mjs +68 -4
  42. package/dist/react.mjs.map +1 -1
  43. package/dist/risk-profile/index.js +6 -0
  44. package/dist/risk-profile/index.js.map +1 -1
  45. package/dist/risk-profile/index.mjs +6 -0
  46. package/dist/risk-profile/index.mjs.map +1 -1
  47. package/dist/scores/index.js +6 -0
  48. package/dist/scores/index.js.map +1 -1
  49. package/dist/scores/index.mjs +6 -0
  50. package/dist/scores/index.mjs.map +1 -1
  51. package/dist/tax/index.js +6 -0
  52. package/dist/tax/index.js.map +1 -1
  53. package/dist/tax/index.mjs +6 -0
  54. package/dist/tax/index.mjs.map +1 -1
  55. package/dist/webhooks/index.d.mts +2 -189
  56. package/dist/webhooks/index.d.ts +2 -189
  57. package/dist/webhooks/index.js +85 -21
  58. package/dist/webhooks/index.js.map +1 -1
  59. package/dist/webhooks/index.mjs +85 -22
  60. package/dist/webhooks/index.mjs.map +1 -1
  61. package/package.json +4 -1
@@ -309,6 +309,12 @@ var BaseClient = class {
309
309
  if (!config.tenantId?.trim()) {
310
310
  throw new ValidationError("tenantId is required and must be a non-empty string", ["tenantId"]);
311
311
  }
312
+ if (typeof fetch === "undefined") {
313
+ throw new VesantError(
314
+ "The Vesant SDK requires a global fetch (Node.js >= 18). Upgrade Node or provide a fetch polyfill.",
315
+ "RUNTIME_UNSUPPORTED"
316
+ );
317
+ }
312
318
  this.interceptors = config.interceptors || [];
313
319
  this.logger = config.logger || createConsoleLogger();
314
320
  let environment = config.environment;
@@ -653,6 +659,61 @@ var BaseClient = class {
653
659
  }
654
660
  };
655
661
 
662
+ // src/geolocation/integrity.ts
663
+ var isNil = (v) => v === null || v === void 0;
664
+ function assessGpsIntegrity(input, opts = {}) {
665
+ const flags = [];
666
+ const now = opts.now ?? (() => Date.now());
667
+ const maxAgeMs = opts.maxAgeMs ?? 6e4;
668
+ const minAccuracy = opts.minAccuracyMeters ?? 1;
669
+ const { accuracy, altitude, altitudeAccuracy, heading, speed, timestamp } = input;
670
+ if (isNil(accuracy)) {
671
+ flags.push("accuracy_missing");
672
+ } else if (accuracy === 0) {
673
+ flags.push("accuracy_zero");
674
+ } else if (accuracy < minAccuracy) {
675
+ flags.push("accuracy_implausibly_small");
676
+ }
677
+ const hasMotion = !isNil(heading) || !isNil(speed);
678
+ if (hasMotion && (isNil(accuracy) || accuracy === 0)) {
679
+ flags.push("motion_without_accuracy");
680
+ }
681
+ if (!isNil(altitude) && isNil(altitudeAccuracy)) {
682
+ flags.push("altitude_without_accuracy");
683
+ }
684
+ if (timestamp !== void 0 && now() - timestamp > maxAgeMs) {
685
+ flags.push("stale_timestamp");
686
+ }
687
+ if (opts.permissionState === "denied" || opts.permissionState === "prompt") {
688
+ flags.push(`permission_${opts.permissionState}`);
689
+ }
690
+ return { suspicious: flags.length > 0, flags };
691
+ }
692
+ function gpsIntegrityInputFromPosition(position) {
693
+ const c = position.coords;
694
+ return {
695
+ latitude: c.latitude,
696
+ longitude: c.longitude,
697
+ accuracy: c.accuracy,
698
+ altitude: c.altitude,
699
+ altitudeAccuracy: c.altitudeAccuracy,
700
+ heading: c.heading,
701
+ speed: c.speed,
702
+ timestamp: position.timestamp
703
+ };
704
+ }
705
+ async function probeGeolocationPermission() {
706
+ try {
707
+ if (typeof navigator === "undefined" || !navigator.permissions?.query) {
708
+ return "unavailable";
709
+ }
710
+ const status = await navigator.permissions.query({ name: "geolocation" });
711
+ return status.state;
712
+ } catch {
713
+ return "unavailable";
714
+ }
715
+ }
716
+
656
717
  // src/geolocation/ciphertext.ts
657
718
  var CIPHER_TEXT_EXPIRY_MINUTES = 5;
658
719
  async function computeHMAC(key, message) {
@@ -705,6 +766,7 @@ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
705
766
  if (typeof navigator === "undefined" || !navigator.geolocation) {
706
767
  return null;
707
768
  }
769
+ const permissionState = await probeGeolocationPermission();
708
770
  return new Promise((resolve) => {
709
771
  navigator.geolocation.getCurrentPosition(
710
772
  (position) => {
@@ -721,6 +783,7 @@ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
721
783
  resolve(null);
722
784
  return;
723
785
  }
786
+ const { flags } = assessGpsIntegrity(gpsIntegrityInputFromPosition(position), { permissionState });
724
787
  resolve({
725
788
  latitude,
726
789
  longitude,
@@ -729,7 +792,8 @@ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
729
792
  altitude_accuracy: position.coords.altitudeAccuracy ?? void 0,
730
793
  heading: position.coords.heading ?? void 0,
731
794
  speed: position.coords.speed ?? void 0,
732
- timestamp: position.timestamp
795
+ timestamp: position.timestamp,
796
+ integrity_flags: flags.length ? flags : void 0
733
797
  });
734
798
  },
735
799
  () => {
@@ -796,6 +860,9 @@ async function generateCipherText(options, config) {
796
860
  );
797
861
  if (location) {
798
862
  locationData = location;
863
+ if (location.integrity_flags?.length) {
864
+ warnings.push(`GPS integrity flags (advisory): ${location.integrity_flags.join(", ")}`);
865
+ }
799
866
  } else if (gpsRequiredByConfig) {
800
867
  throw new VesantError(
801
868
  `GPS location is required for ${options.reason} by tenant configuration, but GPS was not available or permission was denied`,
@@ -915,8 +982,8 @@ var GeolocationClient = class extends BaseClient {
915
982
  * ```
916
983
  */
917
984
  async verifyIP(request, requestOptions) {
918
- if (!request.ip_address?.trim()) {
919
- throw new ValidationError("ip_address is required and must be a non-empty string", ["ip_address"]);
985
+ if (request.ip_address !== void 0 && !request.ip_address.trim()) {
986
+ throw new ValidationError("ip_address, when provided, must be a non-empty string", ["ip_address"]);
920
987
  }
921
988
  return this.requestWithRetry("/api/v1/geo/verify", {
922
989
  method: "POST",
@@ -1266,20 +1333,12 @@ var GeolocationClient = class extends BaseClient {
1266
1333
  *
1267
1334
  * @example
1268
1335
  * ```typescript
1269
- * // Using GPS (preferred)
1336
+ * // GPS (the web SDK is GPS + IP only; the server handles the IP fallback)
1270
1337
  * const result = await client.captureLocation(token, {
1271
1338
  * latitude: 37.7749,
1272
1339
  * longitude: -122.4194,
1273
1340
  * accuracy: 10
1274
1341
  * });
1275
- *
1276
- * // Using WiFi positioning (fallback)
1277
- * const result = await client.captureLocation(token, {
1278
- * wifi_networks: [
1279
- * { macAddress: "00:11:22:33:44:55", signalStrength: -50 },
1280
- * { macAddress: "AA:BB:CC:DD:EE:FF", signalStrength: -70 }
1281
- * ]
1282
- * });
1283
1342
  * ```
1284
1343
  */
1285
1344
  async captureLocation(token, capture, requestOptions) {
@@ -1326,6 +1385,6 @@ var GeolocationClient = class extends BaseClient {
1326
1385
  // ============================================================================
1327
1386
  };
1328
1387
 
1329
- export { GeolocationClient, decodeCipherText, generateCipherText, isCipherTextExpired };
1388
+ export { GeolocationClient, assessGpsIntegrity, decodeCipherText, generateCipherText, gpsIntegrityInputFromPosition, isCipherTextExpired, probeGeolocationPermission };
1330
1389
  //# sourceMappingURL=index.mjs.map
1331
1390
  //# sourceMappingURL=index.mjs.map