@astrasyncai/verification-gateway 4.2.0 → 4.3.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.
Files changed (112) hide show
  1. package/README.md +45 -21
  2. package/dist/adapter-interface/interface.d.mts +2 -2
  3. package/dist/adapter-interface/interface.d.ts +2 -2
  4. package/dist/adapters/express.d.mts +2 -2
  5. package/dist/adapters/express.d.ts +2 -2
  6. package/dist/adapters/express.js +56 -4
  7. package/dist/adapters/express.js.map +1 -1
  8. package/dist/adapters/express.mjs +56 -4
  9. package/dist/adapters/express.mjs.map +1 -1
  10. package/dist/adapters/mcp.d.mts +38 -30
  11. package/dist/adapters/mcp.d.ts +38 -30
  12. package/dist/adapters/mcp.js +22 -5
  13. package/dist/adapters/mcp.js.map +1 -1
  14. package/dist/adapters/mcp.mjs +22 -5
  15. package/dist/adapters/mcp.mjs.map +1 -1
  16. package/dist/adapters/nextjs.d.mts +2 -2
  17. package/dist/adapters/nextjs.d.ts +2 -2
  18. package/dist/adapters/nextjs.js +54 -4
  19. package/dist/adapters/nextjs.js.map +1 -1
  20. package/dist/adapters/nextjs.mjs +54 -4
  21. package/dist/adapters/nextjs.mjs.map +1 -1
  22. package/dist/adapters/sdk.d.mts +2 -2
  23. package/dist/adapters/sdk.d.ts +2 -2
  24. package/dist/agent/index.d.mts +2 -2
  25. package/dist/agent/index.d.ts +2 -2
  26. package/dist/agent/index.js +2 -2
  27. package/dist/agent/index.js.map +1 -1
  28. package/dist/agent/index.mjs +2 -2
  29. package/dist/agent/index.mjs.map +1 -1
  30. package/dist/bin/astrasync-claude-hook.js +2 -2
  31. package/dist/bin/astrasync-codex-hook.js +2 -2
  32. package/dist/bin/astrasync-guard.js +2 -2
  33. package/dist/bin/astrasync.js +14 -4
  34. package/dist/browser/background.js +2 -2
  35. package/dist/browser/background.js.map +1 -1
  36. package/dist/browser/background.mjs +2 -2
  37. package/dist/browser/background.mjs.map +1 -1
  38. package/dist/browser/browser-adapter.d.mts +2 -2
  39. package/dist/browser/browser-adapter.d.ts +2 -2
  40. package/dist/claude-code/claude-code-adapter.d.mts +2 -2
  41. package/dist/claude-code/claude-code-adapter.d.ts +2 -2
  42. package/dist/cli/index.d.mts +2 -2
  43. package/dist/cli/index.d.ts +2 -2
  44. package/dist/codex/index.d.mts +2 -2
  45. package/dist/codex/index.d.ts +2 -2
  46. package/dist/codex/index.js +2 -2
  47. package/dist/codex/index.js.map +1 -1
  48. package/dist/codex/index.mjs +2 -2
  49. package/dist/codex/index.mjs.map +1 -1
  50. package/dist/cursor/cursor-adapter.d.mts +2 -2
  51. package/dist/cursor/cursor-adapter.d.ts +2 -2
  52. package/dist/cursor/extension.d.mts +2 -2
  53. package/dist/cursor/extension.d.ts +2 -2
  54. package/dist/cursor/extension.js +2 -2
  55. package/dist/cursor/extension.js.map +1 -1
  56. package/dist/cursor/extension.mjs +2 -2
  57. package/dist/cursor/extension.mjs.map +1 -1
  58. package/dist/edge-config.d.mts +1 -1
  59. package/dist/edge-config.d.ts +1 -1
  60. package/dist/edge-core/index.d.mts +1 -1
  61. package/dist/edge-core/index.d.ts +1 -1
  62. package/dist/edge-core/index.js +25 -5
  63. package/dist/edge-core/index.js.map +1 -1
  64. package/dist/edge-core/index.mjs +25 -5
  65. package/dist/edge-core/index.mjs.map +1 -1
  66. package/dist/{express-D_4hTn5Z.d.mts → express-CR6F3njD.d.mts} +1 -1
  67. package/dist/{express-BVd1_3FE.d.ts → express-DaqL11tx.d.ts} +1 -1
  68. package/dist/gateway/gateway.d.mts +2 -2
  69. package/dist/gateway/gateway.d.ts +2 -2
  70. package/dist/gateway/gateway.js +2 -2
  71. package/dist/gateway/gateway.js.map +1 -1
  72. package/dist/gateway/gateway.mjs +2 -2
  73. package/dist/gateway/gateway.mjs.map +1 -1
  74. package/dist/git-trigger/git-hooks.d.mts +2 -2
  75. package/dist/git-trigger/git-hooks.d.ts +2 -2
  76. package/dist/{index-B0YHu_SP.d.ts → index-B5Ts1WtM.d.ts} +3 -3
  77. package/dist/{index-T1aBoUcc.d.ts → index-BfIxCYIZ.d.ts} +1 -1
  78. package/dist/{index-BPEBlOsE.d.mts → index-Cub7lK-T.d.mts} +3 -3
  79. package/dist/{index-DQb5-_1X.d.mts → index-CwAh7Tln.d.mts} +1 -1
  80. package/dist/index.d.mts +7 -7
  81. package/dist/index.d.ts +7 -7
  82. package/dist/index.js +74 -35
  83. package/dist/index.js.map +1 -1
  84. package/dist/index.mjs +71 -32
  85. package/dist/index.mjs.map +1 -1
  86. package/dist/local-evaluator/evaluator.d.mts +2 -2
  87. package/dist/local-evaluator/evaluator.d.ts +2 -2
  88. package/dist/metadata-capture.d.mts +18 -5
  89. package/dist/metadata-capture.d.ts +18 -5
  90. package/dist/metadata-capture.js +21 -4
  91. package/dist/metadata-capture.js.map +1 -1
  92. package/dist/metadata-capture.mjs +20 -4
  93. package/dist/metadata-capture.mjs.map +1 -1
  94. package/dist/{nextjs-w7RTbP1P.d.ts → nextjs-DL6uE1ye.d.ts} +1 -1
  95. package/dist/{nextjs-WyeVr2Kp.d.mts → nextjs-DlX6xwbU.d.mts} +1 -1
  96. package/dist/{sdk-CbTNIkAa.d.mts → sdk-Bbh9B_dw.d.mts} +1 -1
  97. package/dist/{sdk-QeX0Z8Ho.d.ts → sdk-C6SASmsh.d.ts} +1 -1
  98. package/dist/transport/index.d.mts +2 -2
  99. package/dist/transport/index.d.ts +2 -2
  100. package/dist/transport/index.js +5 -5
  101. package/dist/transport/index.js.map +1 -1
  102. package/dist/transport/index.mjs +2 -2
  103. package/dist/transport/index.mjs.map +1 -1
  104. package/dist/{types-r850cOt0.d.mts → types-C0zfSXMB.d.mts} +22 -0
  105. package/dist/{types-DqfPU5Bl.d.mts → types-C7Rb-w0d.d.mts} +1 -1
  106. package/dist/{types-sMxBT-nM.d.ts → types-DwSfO7Sb.d.ts} +22 -0
  107. package/dist/{types-BLUx92FJ.d.ts → types-nIh3HtuA.d.ts} +1 -1
  108. package/dist/ui/index.d.mts +1 -1
  109. package/dist/ui/index.d.ts +1 -1
  110. package/dist/verify.d.mts +1 -1
  111. package/dist/verify.d.ts +1 -1
  112. package/package.json +2 -4
@@ -741,7 +741,9 @@ var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set([
741
741
  "x-astrasync-signature",
742
742
  "x-astrasync-secret",
743
743
  "x-hub-signature",
744
- "x-hub-signature-256"
744
+ "x-hub-signature-256",
745
+ // Short-lived verify dedupe token — must never persist in stored metadata.
746
+ "x-astra-verified-hop"
745
747
  ]);
746
748
  var SECRET_HEADER_PREFIXES = ["x-astrasync-", "kya-", "kya_"];
747
749
  var CREDENTIAL_HEADER_NAMES = /* @__PURE__ */ new Set([
@@ -876,16 +878,25 @@ var CONNECTION_HEADER_SOURCES = [
876
878
  ["cf-ipcountry", "x-vercel-ip-country", "cloudfront-viewer-country", "fastly-geo-country"]
877
879
  ],
878
880
  ["region", ["x-vercel-ip-country-region", "cloudfront-viewer-country-region"]],
881
+ ["countryRegionName", ["cloudfront-viewer-country-region-name"]],
879
882
  ["city", ["x-vercel-ip-city", "cloudfront-viewer-city"]],
880
883
  ["asn", ["cloudfront-viewer-asn"]],
881
884
  ["tlsVersion", ["cloudfront-viewer-tls"]],
882
885
  ["httpVersion", ["cloudfront-viewer-http-version"]],
886
+ ["timeZone", ["x-vercel-ip-timezone", "cloudfront-viewer-time-zone"]],
887
+ ["metroCode", ["cloudfront-viewer-metro-code"]],
883
888
  // TLS fingerprints can only be computed where TLS terminates. When a CDN
884
889
  // terminates TLS in front of the merchant, its fingerprint headers ARE the
885
890
  // connection-layer truth — normalising them here is the permanent design.
886
- ["tlsFingerprint", ["cf-ja3-hash"]],
887
- ["ja4", ["cf-ja4"]]
891
+ // CloudFront delivers JA3/JA4 only via an origin request policy and only
892
+ // for HTTPS viewer connections.
893
+ ["tlsFingerprint", ["cf-ja3-hash", "cloudfront-viewer-ja3-fingerprint"]],
894
+ ["ja4", ["cf-ja4", "cloudfront-viewer-ja4-fingerprint"]],
895
+ // Header-structure fingerprint: browser/SDK-distinctive header ordering.
896
+ ["headerOrder", ["cloudfront-viewer-header-order"]],
897
+ ["headerCount", ["cloudfront-viewer-header-count"]]
888
898
  ];
899
+ var MAX_CONNECTION_VALUE_CHARS = 256;
889
900
  function deriveConnectionFromHeaders(headers) {
890
901
  if (!headers) return void 0;
891
902
  const lower = {};
@@ -898,11 +909,15 @@ function deriveConnectionFromHeaders(headers) {
898
909
  for (const source of sources) {
899
910
  const value = lower[source]?.trim();
900
911
  if (value) {
901
- connection[key] = value;
912
+ connection[key] = value.slice(0, MAX_CONNECTION_VALUE_CHARS);
902
913
  break;
903
914
  }
904
915
  }
905
916
  }
917
+ if (!connection.ip) {
918
+ const addr = lower["cloudfront-viewer-address"]?.trim();
919
+ if (addr) connection.ip = addr.replace(/:\d+$/, "");
920
+ }
906
921
  if (!connection.ip) {
907
922
  const xff = lower["x-forwarded-for"];
908
923
  const client = xff?.split(",")[0]?.trim();
@@ -1315,6 +1330,31 @@ function annotateApprovalRequired(result) {
1315
1330
  result.denialReasons = [APPROVAL_REASON, ...result.denialReasons ?? []];
1316
1331
  }
1317
1332
 
1333
+ // src/verified-hop.ts
1334
+ var MCP_VERIFIED_HOP_HEADER = "X-Astra-Verified-Hop";
1335
+ var MCP_VERIFIED_HOP_MAX_AGE_MS = 6e4;
1336
+ function parseVerifiedHop(value) {
1337
+ if (!value) return null;
1338
+ const parts = value.split(";");
1339
+ if (parts.length !== 3) return null;
1340
+ const [astraId, sessionId, checkedAtRaw] = parts;
1341
+ if (!astraId) return null;
1342
+ const checkedAt = Number(checkedAtRaw);
1343
+ if (!Number.isFinite(checkedAt) || checkedAt <= 0) return null;
1344
+ return {
1345
+ astraId,
1346
+ ...sessionId ? { sessionId } : {},
1347
+ checkedAt
1348
+ };
1349
+ }
1350
+ function isVerifiedHopValidFor(marker, expectedAstraId, opts = {}) {
1351
+ if (!marker) return false;
1352
+ if (marker.astraId !== expectedAstraId) return false;
1353
+ const maxAge = opts.maxAgeMs ?? MCP_VERIFIED_HOP_MAX_AGE_MS;
1354
+ const now = opts.now ?? Date.now();
1355
+ return now - marker.checkedAt <= maxAge && now >= marker.checkedAt;
1356
+ }
1357
+
1318
1358
  // src/adapters/nextjs.ts
1319
1359
  function escapeHtml(value) {
1320
1360
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
@@ -1553,6 +1593,8 @@ function createMiddleware(options) {
1553
1593
  enableRuntimeChallenge = true,
1554
1594
  routesRefreshMs = DEFAULT_ROUTES_REFRESH_MS,
1555
1595
  anonymousBeacon = true,
1596
+ trustVerifiedHop = false,
1597
+ verifiedHopMaxAgeMs,
1556
1598
  ...config
1557
1599
  } = options;
1558
1600
  const interstitialEnabled = showInterstitial ?? showCommerceShield ?? true;
@@ -1615,6 +1657,14 @@ function createMiddleware(options) {
1615
1657
  return NextResponse.next();
1616
1658
  }
1617
1659
  const credentials = extractCredentialsFromNextRequest(request);
1660
+ if (trustVerifiedHop && credentials.astraId) {
1661
+ const marker = parseVerifiedHop(request.headers.get(MCP_VERIFIED_HOP_HEADER) ?? void 0);
1662
+ if (isVerifiedHopValidFor(marker, credentials.astraId, {
1663
+ ...verifiedHopMaxAgeMs !== void 0 ? { maxAgeMs: verifiedHopMaxAgeMs } : {}
1664
+ })) {
1665
+ return NextResponse.next();
1666
+ }
1667
+ }
1618
1668
  const counterpartyUrl = config.counterpartyUrl || request.nextUrl.origin;
1619
1669
  const pdlssPair = resolveNextPdlss(request, routeConfig);
1620
1670
  const purpose = pdlssPair.purpose;