@astrasyncai/verification-gateway 4.2.1 → 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 (93) 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/bin/astrasync.js +10 -0
  27. package/dist/browser/background.js.map +1 -1
  28. package/dist/browser/background.mjs.map +1 -1
  29. package/dist/browser/browser-adapter.d.mts +2 -2
  30. package/dist/browser/browser-adapter.d.ts +2 -2
  31. package/dist/claude-code/claude-code-adapter.d.mts +2 -2
  32. package/dist/claude-code/claude-code-adapter.d.ts +2 -2
  33. package/dist/cli/index.d.mts +2 -2
  34. package/dist/cli/index.d.ts +2 -2
  35. package/dist/codex/index.d.mts +2 -2
  36. package/dist/codex/index.d.ts +2 -2
  37. package/dist/codex/index.js.map +1 -1
  38. package/dist/codex/index.mjs.map +1 -1
  39. package/dist/cursor/cursor-adapter.d.mts +2 -2
  40. package/dist/cursor/cursor-adapter.d.ts +2 -2
  41. package/dist/cursor/extension.d.mts +2 -2
  42. package/dist/cursor/extension.d.ts +2 -2
  43. package/dist/cursor/extension.js.map +1 -1
  44. package/dist/cursor/extension.mjs.map +1 -1
  45. package/dist/edge-config.d.mts +1 -1
  46. package/dist/edge-config.d.ts +1 -1
  47. package/dist/edge-core/index.d.mts +1 -1
  48. package/dist/edge-core/index.d.ts +1 -1
  49. package/dist/edge-core/index.js +25 -5
  50. package/dist/edge-core/index.js.map +1 -1
  51. package/dist/edge-core/index.mjs +25 -5
  52. package/dist/edge-core/index.mjs.map +1 -1
  53. package/dist/{express-D_4hTn5Z.d.mts → express-CR6F3njD.d.mts} +1 -1
  54. package/dist/{express-BVd1_3FE.d.ts → express-DaqL11tx.d.ts} +1 -1
  55. package/dist/gateway/gateway.d.mts +2 -2
  56. package/dist/gateway/gateway.d.ts +2 -2
  57. package/dist/gateway/gateway.js.map +1 -1
  58. package/dist/gateway/gateway.mjs.map +1 -1
  59. package/dist/git-trigger/git-hooks.d.mts +2 -2
  60. package/dist/git-trigger/git-hooks.d.ts +2 -2
  61. package/dist/{index-BqHKlLOU.d.ts → index-B5Ts1WtM.d.ts} +1 -1
  62. package/dist/{index-T1aBoUcc.d.ts → index-BfIxCYIZ.d.ts} +1 -1
  63. package/dist/{index-BTeQ9fgV.d.mts → index-Cub7lK-T.d.mts} +1 -1
  64. package/dist/{index-DQb5-_1X.d.mts → index-CwAh7Tln.d.mts} +1 -1
  65. package/dist/index.d.mts +7 -7
  66. package/dist/index.d.ts +7 -7
  67. package/dist/index.js +69 -30
  68. package/dist/index.js.map +1 -1
  69. package/dist/index.mjs +69 -30
  70. package/dist/index.mjs.map +1 -1
  71. package/dist/local-evaluator/evaluator.d.mts +2 -2
  72. package/dist/local-evaluator/evaluator.d.ts +2 -2
  73. package/dist/metadata-capture.d.mts +18 -5
  74. package/dist/metadata-capture.d.ts +18 -5
  75. package/dist/metadata-capture.js +21 -4
  76. package/dist/metadata-capture.js.map +1 -1
  77. package/dist/metadata-capture.mjs +20 -4
  78. package/dist/metadata-capture.mjs.map +1 -1
  79. package/dist/{nextjs-w7RTbP1P.d.ts → nextjs-DL6uE1ye.d.ts} +1 -1
  80. package/dist/{nextjs-WyeVr2Kp.d.mts → nextjs-DlX6xwbU.d.mts} +1 -1
  81. package/dist/{sdk-CbTNIkAa.d.mts → sdk-Bbh9B_dw.d.mts} +1 -1
  82. package/dist/{sdk-QeX0Z8Ho.d.ts → sdk-C6SASmsh.d.ts} +1 -1
  83. package/dist/transport/index.d.mts +2 -2
  84. package/dist/transport/index.d.ts +2 -2
  85. package/dist/{types-r850cOt0.d.mts → types-C0zfSXMB.d.mts} +22 -0
  86. package/dist/{types-DqfPU5Bl.d.mts → types-C7Rb-w0d.d.mts} +1 -1
  87. package/dist/{types-sMxBT-nM.d.ts → types-DwSfO7Sb.d.ts} +22 -0
  88. package/dist/{types-BLUx92FJ.d.ts → types-nIh3HtuA.d.ts} +1 -1
  89. package/dist/ui/index.d.mts +1 -1
  90. package/dist/ui/index.d.ts +1 -1
  91. package/dist/verify.d.mts +1 -1
  92. package/dist/verify.d.ts +1 -1
  93. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -996,6 +996,34 @@ function extractHttpCredentials(headers) {
996
996
  return credentials;
997
997
  }
998
998
 
999
+ // src/verified-hop.ts
1000
+ var MCP_VERIFIED_HOP_HEADER = "X-Astra-Verified-Hop";
1001
+ var MCP_VERIFIED_HOP_MAX_AGE_MS = 6e4;
1002
+ function serializeVerifiedHop(marker) {
1003
+ return `${marker.astraId};${marker.sessionId ?? ""};${marker.checkedAt}`;
1004
+ }
1005
+ function parseVerifiedHop(value) {
1006
+ if (!value) return null;
1007
+ const parts = value.split(";");
1008
+ if (parts.length !== 3) return null;
1009
+ const [astraId, sessionId, checkedAtRaw] = parts;
1010
+ if (!astraId) return null;
1011
+ const checkedAt = Number(checkedAtRaw);
1012
+ if (!Number.isFinite(checkedAt) || checkedAt <= 0) return null;
1013
+ return {
1014
+ astraId,
1015
+ ...sessionId ? { sessionId } : {},
1016
+ checkedAt
1017
+ };
1018
+ }
1019
+ function isVerifiedHopValidFor(marker, expectedAstraId, opts = {}) {
1020
+ if (!marker) return false;
1021
+ if (marker.astraId !== expectedAstraId) return false;
1022
+ const maxAge = opts.maxAgeMs ?? MCP_VERIFIED_HOP_MAX_AGE_MS;
1023
+ const now = opts.now ?? Date.now();
1024
+ return now - marker.checkedAt <= maxAge && now >= marker.checkedAt;
1025
+ }
1026
+
999
1027
  // src/adapters/http-pdlss.ts
1000
1028
  var HTTP_METHOD_ACTION_TABLE = {
1001
1029
  GET: "data.read",
@@ -1133,7 +1161,9 @@ var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set([
1133
1161
  "x-astrasync-signature",
1134
1162
  "x-astrasync-secret",
1135
1163
  "x-hub-signature",
1136
- "x-hub-signature-256"
1164
+ "x-hub-signature-256",
1165
+ // Short-lived verify dedupe token — must never persist in stored metadata.
1166
+ "x-astra-verified-hop"
1137
1167
  ]);
1138
1168
  var SECRET_HEADER_PREFIXES = ["x-astrasync-", "kya-", "kya_"];
1139
1169
  var CREDENTIAL_HEADER_NAMES = /* @__PURE__ */ new Set([
@@ -1276,16 +1306,25 @@ var CONNECTION_HEADER_SOURCES = [
1276
1306
  ["cf-ipcountry", "x-vercel-ip-country", "cloudfront-viewer-country", "fastly-geo-country"]
1277
1307
  ],
1278
1308
  ["region", ["x-vercel-ip-country-region", "cloudfront-viewer-country-region"]],
1309
+ ["countryRegionName", ["cloudfront-viewer-country-region-name"]],
1279
1310
  ["city", ["x-vercel-ip-city", "cloudfront-viewer-city"]],
1280
1311
  ["asn", ["cloudfront-viewer-asn"]],
1281
1312
  ["tlsVersion", ["cloudfront-viewer-tls"]],
1282
1313
  ["httpVersion", ["cloudfront-viewer-http-version"]],
1314
+ ["timeZone", ["x-vercel-ip-timezone", "cloudfront-viewer-time-zone"]],
1315
+ ["metroCode", ["cloudfront-viewer-metro-code"]],
1283
1316
  // TLS fingerprints can only be computed where TLS terminates. When a CDN
1284
1317
  // terminates TLS in front of the merchant, its fingerprint headers ARE the
1285
1318
  // connection-layer truth — normalising them here is the permanent design.
1286
- ["tlsFingerprint", ["cf-ja3-hash"]],
1287
- ["ja4", ["cf-ja4"]]
1319
+ // CloudFront delivers JA3/JA4 only via an origin request policy and only
1320
+ // for HTTPS viewer connections.
1321
+ ["tlsFingerprint", ["cf-ja3-hash", "cloudfront-viewer-ja3-fingerprint"]],
1322
+ ["ja4", ["cf-ja4", "cloudfront-viewer-ja4-fingerprint"]],
1323
+ // Header-structure fingerprint: browser/SDK-distinctive header ordering.
1324
+ ["headerOrder", ["cloudfront-viewer-header-order"]],
1325
+ ["headerCount", ["cloudfront-viewer-header-count"]]
1288
1326
  ];
1327
+ var MAX_CONNECTION_VALUE_CHARS = 256;
1289
1328
  function deriveConnectionFromHeaders(headers) {
1290
1329
  if (!headers) return void 0;
1291
1330
  const lower = {};
@@ -1298,11 +1337,15 @@ function deriveConnectionFromHeaders(headers) {
1298
1337
  for (const source of sources) {
1299
1338
  const value = lower[source]?.trim();
1300
1339
  if (value) {
1301
- connection[key] = value;
1340
+ connection[key] = value.slice(0, MAX_CONNECTION_VALUE_CHARS);
1302
1341
  break;
1303
1342
  }
1304
1343
  }
1305
1344
  }
1345
+ if (!connection.ip) {
1346
+ const addr = lower["cloudfront-viewer-address"]?.trim();
1347
+ if (addr) connection.ip = addr.replace(/:\d+$/, "");
1348
+ }
1306
1349
  if (!connection.ip) {
1307
1350
  const xff = lower["x-forwarded-for"];
1308
1351
  const client = xff?.split(",")[0]?.trim();
@@ -1757,6 +1800,8 @@ function createMiddleware(options) {
1757
1800
  failOnError = "open",
1758
1801
  caseInsensitiveRouteMatch = false,
1759
1802
  anonymousBeacon = true,
1803
+ trustVerifiedHop = false,
1804
+ verifiedHopMaxAgeMs,
1760
1805
  ...config
1761
1806
  } = options;
1762
1807
  if (config.apiBaseUrl) {
@@ -1849,6 +1894,16 @@ function createMiddleware(options) {
1849
1894
  beaconPassThrough?.(req);
1850
1895
  return next();
1851
1896
  }
1897
+ if (trustVerifiedHop && credentials.astraId) {
1898
+ const hopRaw = req.headers[MCP_VERIFIED_HOP_HEADER.toLowerCase()];
1899
+ const hopValue = typeof hopRaw === "string" ? hopRaw : Array.isArray(hopRaw) ? hopRaw[0] : void 0;
1900
+ const marker = parseVerifiedHop(hopValue);
1901
+ if (isVerifiedHopValidFor(marker, credentials.astraId, {
1902
+ ...verifiedHopMaxAgeMs !== void 0 ? { maxAgeMs: verifiedHopMaxAgeMs } : {}
1903
+ })) {
1904
+ return next();
1905
+ }
1906
+ }
1852
1907
  const pdlssPair = resolveRequestPdlss(
1853
1908
  req,
1854
1909
  routeConfig,
@@ -2304,6 +2359,8 @@ function createMiddleware2(options) {
2304
2359
  enableRuntimeChallenge = true,
2305
2360
  routesRefreshMs = DEFAULT_ROUTES_REFRESH_MS2,
2306
2361
  anonymousBeacon = true,
2362
+ trustVerifiedHop = false,
2363
+ verifiedHopMaxAgeMs,
2307
2364
  ...config
2308
2365
  } = options;
2309
2366
  const interstitialEnabled = showInterstitial ?? showCommerceShield ?? true;
@@ -2366,6 +2423,14 @@ function createMiddleware2(options) {
2366
2423
  return NextResponse.next();
2367
2424
  }
2368
2425
  const credentials = extractCredentialsFromNextRequest(request);
2426
+ if (trustVerifiedHop && credentials.astraId) {
2427
+ const marker = parseVerifiedHop(request.headers.get(MCP_VERIFIED_HOP_HEADER) ?? void 0);
2428
+ if (isVerifiedHopValidFor(marker, credentials.astraId, {
2429
+ ...verifiedHopMaxAgeMs !== void 0 ? { maxAgeMs: verifiedHopMaxAgeMs } : {}
2430
+ })) {
2431
+ return NextResponse.next();
2432
+ }
2433
+ }
2369
2434
  const counterpartyUrl = config.counterpartyUrl || request.nextUrl.origin;
2370
2435
  const pdlssPair = resolveNextPdlss(request, routeConfig);
2371
2436
  const purpose = pdlssPair.purpose;
@@ -5257,32 +5322,6 @@ function extractCredentialsFromProtocol(protocol, context) {
5257
5322
  }
5258
5323
 
5259
5324
  // src/transport/mcp-server.ts
5260
- var MCP_VERIFIED_HOP_HEADER = "X-Astra-Verified-Hop";
5261
- var MCP_VERIFIED_HOP_MAX_AGE_MS = 6e4;
5262
- function serializeVerifiedHop(marker) {
5263
- return `${marker.astraId};${marker.sessionId ?? ""};${marker.checkedAt}`;
5264
- }
5265
- function parseVerifiedHop(value) {
5266
- if (!value) return null;
5267
- const parts = value.split(";");
5268
- if (parts.length !== 3) return null;
5269
- const [astraId, sessionId, checkedAtRaw] = parts;
5270
- if (!astraId) return null;
5271
- const checkedAt = Number(checkedAtRaw);
5272
- if (!Number.isFinite(checkedAt) || checkedAt <= 0) return null;
5273
- return {
5274
- astraId,
5275
- ...sessionId ? { sessionId } : {},
5276
- checkedAt
5277
- };
5278
- }
5279
- function isVerifiedHopValidFor(marker, expectedAstraId, opts = {}) {
5280
- if (!marker) return false;
5281
- if (marker.astraId !== expectedAstraId) return false;
5282
- const maxAge = opts.maxAgeMs ?? MCP_VERIFIED_HOP_MAX_AGE_MS;
5283
- const now = opts.now ?? Date.now();
5284
- return now - marker.checkedAt <= maxAge && now >= marker.checkedAt;
5285
- }
5286
5325
  function parseMcpJsonRpc(body) {
5287
5326
  if (!body || typeof body !== "object" || Array.isArray(body)) return null;
5288
5327
  const obj = body;