@astrasyncai/verification-gateway 3.11.1 → 4.0.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 (99) hide show
  1. package/dist/adapter-interface/interface.d.mts +2 -2
  2. package/dist/adapter-interface/interface.d.ts +2 -2
  3. package/dist/adapters/express.d.mts +2 -2
  4. package/dist/adapters/express.d.ts +2 -2
  5. package/dist/adapters/express.js +106 -10
  6. package/dist/adapters/express.js.map +1 -1
  7. package/dist/adapters/express.mjs +106 -10
  8. package/dist/adapters/express.mjs.map +1 -1
  9. package/dist/adapters/mcp.d.mts +1 -1
  10. package/dist/adapters/mcp.d.ts +1 -1
  11. package/dist/adapters/mcp.js +111 -10
  12. package/dist/adapters/mcp.js.map +1 -1
  13. package/dist/adapters/mcp.mjs +111 -10
  14. package/dist/adapters/mcp.mjs.map +1 -1
  15. package/dist/adapters/nextjs.d.mts +2 -2
  16. package/dist/adapters/nextjs.d.ts +2 -2
  17. package/dist/adapters/nextjs.js +107 -10
  18. package/dist/adapters/nextjs.js.map +1 -1
  19. package/dist/adapters/nextjs.mjs +107 -10
  20. package/dist/adapters/nextjs.mjs.map +1 -1
  21. package/dist/adapters/sdk.d.mts +2 -2
  22. package/dist/adapters/sdk.d.ts +2 -2
  23. package/dist/adapters/sdk.js +92 -10
  24. package/dist/adapters/sdk.js.map +1 -1
  25. package/dist/adapters/sdk.mjs +92 -10
  26. package/dist/adapters/sdk.mjs.map +1 -1
  27. package/dist/agent/index.d.mts +2 -2
  28. package/dist/agent/index.d.ts +2 -2
  29. package/dist/bin/astrasync-claude-hook.js +92 -10
  30. package/dist/bin/astrasync-codex-hook.js +92 -10
  31. package/dist/bin/astrasync-guard.js +92 -10
  32. package/dist/bin/astrasync.js +93 -10
  33. package/dist/browser/background.js +92 -10
  34. package/dist/browser/background.js.map +1 -1
  35. package/dist/browser/background.mjs +92 -10
  36. package/dist/browser/background.mjs.map +1 -1
  37. package/dist/browser/browser-adapter.d.mts +2 -2
  38. package/dist/browser/browser-adapter.d.ts +2 -2
  39. package/dist/claude-code/claude-code-adapter.d.mts +2 -2
  40. package/dist/claude-code/claude-code-adapter.d.ts +2 -2
  41. package/dist/cli/index.d.mts +2 -2
  42. package/dist/cli/index.d.ts +2 -2
  43. package/dist/codex/index.d.mts +2 -2
  44. package/dist/codex/index.d.ts +2 -2
  45. package/dist/codex/index.js +92 -10
  46. package/dist/codex/index.js.map +1 -1
  47. package/dist/codex/index.mjs +92 -10
  48. package/dist/codex/index.mjs.map +1 -1
  49. package/dist/cursor/cursor-adapter.d.mts +2 -2
  50. package/dist/cursor/cursor-adapter.d.ts +2 -2
  51. package/dist/cursor/extension.d.mts +2 -2
  52. package/dist/cursor/extension.d.ts +2 -2
  53. package/dist/cursor/extension.js +92 -10
  54. package/dist/cursor/extension.js.map +1 -1
  55. package/dist/cursor/extension.mjs +92 -10
  56. package/dist/cursor/extension.mjs.map +1 -1
  57. package/dist/edge-config.d.mts +1 -1
  58. package/dist/edge-config.d.ts +1 -1
  59. package/dist/{express-DCXa1oqj.d.mts → express-BZajRs4i.d.mts} +1 -1
  60. package/dist/{express-ClNtDhhc.d.ts → express-CjCUB1k7.d.ts} +1 -1
  61. package/dist/gateway/gateway.d.mts +2 -2
  62. package/dist/gateway/gateway.d.ts +2 -2
  63. package/dist/gateway/gateway.js +92 -10
  64. package/dist/gateway/gateway.js.map +1 -1
  65. package/dist/gateway/gateway.mjs +92 -10
  66. package/dist/gateway/gateway.mjs.map +1 -1
  67. package/dist/git-trigger/git-hooks.d.mts +2 -2
  68. package/dist/git-trigger/git-hooks.d.ts +2 -2
  69. package/dist/{index-BrNKDmiR.d.mts → index-B0cyMZDL.d.mts} +1 -1
  70. package/dist/{index-Dr_XiN65.d.mts → index-BRYteOqO.d.mts} +1 -1
  71. package/dist/{index-CfHurO1P.d.ts → index-BZQdVqNw.d.ts} +1 -1
  72. package/dist/{index-D2ztkumS.d.ts → index-adgKhujR.d.ts} +1 -1
  73. package/dist/index.d.mts +9 -9
  74. package/dist/index.d.ts +9 -9
  75. package/dist/index.js +160 -10
  76. package/dist/index.js.map +1 -1
  77. package/dist/index.mjs +159 -10
  78. package/dist/index.mjs.map +1 -1
  79. package/dist/local-evaluator/evaluator.d.mts +2 -2
  80. package/dist/local-evaluator/evaluator.d.ts +2 -2
  81. package/dist/{nextjs-CEBVBsdi.d.ts → nextjs-D_iFf5k-.d.ts} +1 -1
  82. package/dist/{nextjs-DcQIk6Zj.d.mts → nextjs-DeUTnOBd.d.mts} +1 -1
  83. package/dist/{sdk-H0JCLW2y.d.ts → sdk-BM3mwEAq.d.ts} +1 -1
  84. package/dist/{sdk-CZkbSOeO.d.mts → sdk-_il1Q41f.d.mts} +1 -1
  85. package/dist/transport/index.d.mts +2 -2
  86. package/dist/transport/index.d.ts +2 -2
  87. package/dist/{types-sy3tq8lp.d.mts → types-BcDf9Kk0.d.mts} +118 -1
  88. package/dist/{types-DhFPiZ3t.d.ts → types-CHKCgDFC.d.ts} +1 -1
  89. package/dist/{types-cQVCMeNV.d.mts → types-DfnP7JiM.d.mts} +1 -1
  90. package/dist/{types-9tns4wyl.d.ts → types-fTQD448H.d.ts} +118 -1
  91. package/dist/ui/index.d.mts +1 -1
  92. package/dist/ui/index.d.ts +1 -1
  93. package/dist/verify.d.mts +15 -2
  94. package/dist/verify.d.ts +15 -2
  95. package/dist/verify.js +117 -10
  96. package/dist/verify.js.map +1 -1
  97. package/dist/verify.mjs +115 -10
  98. package/dist/verify.mjs.map +1 -1
  99. package/package.json +1 -1
package/dist/verify.js CHANGED
@@ -20,12 +20,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/verify.ts
21
21
  var verify_exports = {};
22
22
  __export(verify_exports, {
23
+ _resetInitCheck: () => _resetInitCheck,
23
24
  clearCache: () => clearCache,
24
25
  extractCredentials: () => extractCredentials,
25
26
  fetchRoutes: () => fetchRoutes,
26
27
  hasCredentials: () => hasCredentials,
27
28
  quickVerify: () => quickVerify,
28
29
  recordDecision: () => recordDecision,
30
+ reportAttempt: () => reportAttempt,
29
31
  reportCounterpartyPreCheckFailure: () => reportCounterpartyPreCheckFailure,
30
32
  reportUnregisteredAttempt: () => reportUnregisteredAttempt,
31
33
  verify: () => verify,
@@ -42,7 +44,7 @@ function getTrustLevel(score) {
42
44
  }
43
45
 
44
46
  // src/version.ts
45
- var SDK_VERSION = "3.11.1";
47
+ var SDK_VERSION = "4.0.0";
46
48
 
47
49
  // src/well-known.ts
48
50
  var CACHE_TTL_MS = 60 * 60 * 1e3;
@@ -67,8 +69,11 @@ var DEFAULT_CONFIG = {
67
69
  debug: false
68
70
  };
69
71
  var initCheckPerformed = false;
72
+ function _resetInitCheck() {
73
+ initCheckPerformed = false;
74
+ }
70
75
  var deprecationWarningShown = false;
71
- async function performInitCheck(apiBaseUrl, debug, strictInit) {
76
+ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
72
77
  initCheckPerformed = true;
73
78
  try {
74
79
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
@@ -85,6 +90,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
85
90
  `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
86
91
  );
87
92
  }
93
+ if (apiKey) {
94
+ const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
95
+ headers: { Authorization: `Bearer ${apiKey}` }
96
+ });
97
+ if (selfCheck.status === 401) {
98
+ const body = await selfCheck.json().catch(() => ({}));
99
+ const message = `[VerificationGateway] the configured AstraSync API key was REJECTED at startup (${body.code ?? "api_key_invalid"}: ${body.message ?? "invalid key"}). Every inbound agent will be turned away until the key is rotated` + (body.remediation?.manageUrl ? ` at ${body.remediation.manageUrl}` : "") + `.`;
100
+ if (strictInit) {
101
+ throw new Error(`${message} (strictInit=true)`);
102
+ }
103
+ console.error(message);
104
+ } else if (selfCheck.ok) {
105
+ const body = await selfCheck.json().catch(() => ({}));
106
+ if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
107
+ console.warn(
108
+ `[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
109
+ );
110
+ } else if (debug) {
111
+ console.log("[VerificationGateway] API key self-check passed");
112
+ }
113
+ }
114
+ }
88
115
  } catch (err) {
89
116
  if (strictInit) {
90
117
  throw err;
@@ -202,8 +229,17 @@ function hasCredentials(credentials) {
202
229
  function createGuidanceResponse(_config, reason, options = {}) {
203
230
  const source = options.source ?? "no_credentials";
204
231
  const isApiError = source === "api_error";
232
+ const isMisconfig = source === "merchant_misconfig";
205
233
  const urls = options.urls;
206
- const guidance = isApiError ? {
234
+ const guidance = isMisconfig ? {
235
+ message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or rotated). Your identity and the AstraSync platform are fine \u2014 contact the site operator. Retrying will not help.",
236
+ registrationUrl: urls?.registrationUrl ?? "",
237
+ documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
238
+ steps: [
239
+ "Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
240
+ "Do not retry: the failure is deterministic until the operator updates their key"
241
+ ]
242
+ } : isApiError ? {
207
243
  message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
208
244
  registrationUrl: urls?.registrationUrl ?? "",
209
245
  documentationUrl: urls?.documentationUrl ?? "",
@@ -241,14 +277,24 @@ function createGuidanceResponse(_config, reason, options = {}) {
241
277
  // partners (and their custom onDenied handlers) can branch on
242
278
  // dimension. Without this, the synthesised stub was indistinguishable
243
279
  // from a real policy deny.
244
- failures: isApiError ? [
280
+ failures: isMisconfig ? [
281
+ {
282
+ dimension: "verify_access.merchant_misconfigured",
283
+ message: reason ?? "The integration API key was rejected by AstraSync",
284
+ guidance: guidance.message
285
+ }
286
+ ] : isApiError ? [
245
287
  {
246
288
  dimension: "verify_access.api_error",
247
289
  message: reason ?? "Verification temporarily unavailable",
248
290
  guidance: guidance.message
249
291
  }
250
292
  ] : void 0,
293
+ // 4.0.0: typed marker so adapters render the misconfig envelope (503 +
294
+ // MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
295
+ ...isMisconfig && { misconfigured: true },
251
296
  correlationId: options.correlationId,
297
+ attemptId: options.attemptId,
252
298
  verifiedAt: /* @__PURE__ */ new Date()
253
299
  };
254
300
  }
@@ -278,6 +324,8 @@ async function callVerifyAccessAPI(config, request) {
278
324
  body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
279
325
  if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
280
326
  if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
327
+ if (requestData.attemptId) body.attemptId = requestData.attemptId;
328
+ if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
281
329
  body.sdkVersion = SDK_VERSION;
282
330
  if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
283
331
  const meta = {
@@ -299,12 +347,16 @@ async function callVerifyAccessAPI(config, request) {
299
347
  const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
300
348
  method: "POST",
301
349
  headers,
302
- body: JSON.stringify(body)
350
+ body: JSON.stringify(body),
351
+ signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
303
352
  });
304
353
  const data = await response.json();
305
354
  if (response.status === 410) {
306
355
  return {
307
356
  success: true,
357
+ // 3.12.0 (Trust Record): keep the server-echoed attempt handle even on
358
+ // the synthesised 410 deny shape (echoed on every branch).
359
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
308
360
  access: {
309
361
  allowed: false,
310
362
  accessLevel: "none",
@@ -320,10 +372,22 @@ async function callVerifyAccessAPI(config, request) {
320
372
  };
321
373
  }
322
374
  if (!response.ok) {
375
+ if (response.status === 401) {
376
+ return {
377
+ success: false,
378
+ error: data.message || data.error || "Integration API key rejected",
379
+ misconfig: true,
380
+ misconfigCode: typeof data?.code === "string" ? data.code : void 0,
381
+ remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
382
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
383
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
384
+ };
385
+ }
323
386
  return {
324
387
  success: false,
325
388
  error: data.message || data.error || `API returned ${response.status}`,
326
- correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0
389
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
390
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
327
391
  };
328
392
  }
329
393
  return data;
@@ -340,9 +404,19 @@ async function verify(config, request, options) {
340
404
  const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
341
405
  if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
342
406
  if (mergedConfig.strictInit) {
343
- await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
407
+ await performInitCheck(
408
+ mergedConfig.apiBaseUrl,
409
+ mergedConfig.debug,
410
+ true,
411
+ mergedConfig.apiKey
412
+ );
344
413
  } else {
345
- void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, false);
414
+ void performInitCheck(
415
+ mergedConfig.apiBaseUrl,
416
+ mergedConfig.debug,
417
+ false,
418
+ mergedConfig.apiKey
419
+ );
346
420
  }
347
421
  }
348
422
  if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
@@ -357,7 +431,13 @@ async function verify(config, request, options) {
357
431
  if (mergedConfig.debug) {
358
432
  console.log("[VerificationGateway] Returning cached result");
359
433
  }
360
- return cached;
434
+ const hit = { ...cached };
435
+ if (request.attemptId) {
436
+ hit.attemptId = request.attemptId;
437
+ } else {
438
+ delete hit.attemptId;
439
+ }
440
+ return hit;
361
441
  }
362
442
  }
363
443
  const enrichedRequest = { ...request };
@@ -375,8 +455,10 @@ async function verify(config, request, options) {
375
455
  const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
376
456
  if (!apiResponse.success) {
377
457
  return createGuidanceResponse(mergedConfig, apiResponse.error, {
378
- source: "api_error",
458
+ source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
379
459
  correlationId: apiResponse.correlationId,
460
+ attemptId: apiResponse.attemptId,
461
+ remediation: apiResponse.remediation,
380
462
  urls
381
463
  });
382
464
  }
@@ -412,6 +494,9 @@ async function verify(config, request, options) {
412
494
  // Anonymous traffic has no session → correlationId is the per-attempt
413
495
  // linking key (the sessionId-equivalent for anonymous callers).
414
496
  correlationId: apiResponse.correlationId,
497
+ // 3.12.0 (Trust Record): server echoes the attempt-chain handle on
498
+ // every branch — denials included (the funnel outlives one deny).
499
+ attemptId: apiResponse.attemptId,
415
500
  recommendation: apiResponse.recommendation,
416
501
  recommendationReasons: apiResponse.recommendationReasons,
417
502
  stepUpApproval: apiResponse.stepUpApproval,
@@ -463,6 +548,8 @@ async function verify(config, request, options) {
463
548
  // v2.3.10 (defect #34, round-4): anonymous responses surface correlationId
464
549
  // (no session row exists for unverified callers).
465
550
  correlationId: apiResponse.correlationId,
551
+ // 3.12.0 (Trust Record): server-echoed attempt-chain handle.
552
+ attemptId: apiResponse.attemptId,
466
553
  runtimeChallenge: apiResponse.runtimeChallenge,
467
554
  tokenGuidance: apiResponse.tokenGuidance,
468
555
  recommendation: apiResponse.recommendation,
@@ -507,6 +594,24 @@ async function recordDecision(config, sessionId, decision, reason) {
507
594
  }).catch(() => {
508
595
  });
509
596
  }
597
+ async function reportAttempt(config, report) {
598
+ const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
599
+ const headers = { "Content-Type": "application/json" };
600
+ if (config.apiKey) {
601
+ headers["Authorization"] = `Bearer ${config.apiKey}`;
602
+ headers["X-API-Key"] = config.apiKey;
603
+ }
604
+ const body = {
605
+ ...report,
606
+ ...!report.counterpartyId && config.counterpartyId && { counterpartyId: config.counterpartyId }
607
+ };
608
+ await fetch(`${apiBaseUrl}/agents/verify-access/attempt-report`, {
609
+ method: "POST",
610
+ headers,
611
+ body: JSON.stringify(body)
612
+ }).catch(() => {
613
+ });
614
+ }
510
615
  async function fetchRoutes(config, counterpartyId) {
511
616
  if (!counterpartyId) return null;
512
617
  const headers = { "Content-Type": "application/json" };
@@ -579,12 +684,14 @@ async function quickVerify(config, credentials) {
579
684
  }
580
685
  // Annotate the CommonJS export names for ESM import in node:
581
686
  0 && (module.exports = {
687
+ _resetInitCheck,
582
688
  clearCache,
583
689
  extractCredentials,
584
690
  fetchRoutes,
585
691
  hasCredentials,
586
692
  quickVerify,
587
693
  recordDecision,
694
+ reportAttempt,
588
695
  reportCounterpartyPreCheckFailure,
589
696
  reportUnregisteredAttempt,
590
697
  verify,