@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.mjs CHANGED
@@ -7,7 +7,7 @@ function getTrustLevel(score) {
7
7
  }
8
8
 
9
9
  // src/version.ts
10
- var SDK_VERSION = "3.11.1";
10
+ var SDK_VERSION = "4.0.0";
11
11
 
12
12
  // src/well-known.ts
13
13
  var CACHE_TTL_MS = 60 * 60 * 1e3;
@@ -32,8 +32,11 @@ var DEFAULT_CONFIG = {
32
32
  debug: false
33
33
  };
34
34
  var initCheckPerformed = false;
35
+ function _resetInitCheck() {
36
+ initCheckPerformed = false;
37
+ }
35
38
  var deprecationWarningShown = false;
36
- async function performInitCheck(apiBaseUrl, debug, strictInit) {
39
+ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
37
40
  initCheckPerformed = true;
38
41
  try {
39
42
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
@@ -50,6 +53,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
50
53
  `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
51
54
  );
52
55
  }
56
+ if (apiKey) {
57
+ const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
58
+ headers: { Authorization: `Bearer ${apiKey}` }
59
+ });
60
+ if (selfCheck.status === 401) {
61
+ const body = await selfCheck.json().catch(() => ({}));
62
+ 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}` : "") + `.`;
63
+ if (strictInit) {
64
+ throw new Error(`${message} (strictInit=true)`);
65
+ }
66
+ console.error(message);
67
+ } else if (selfCheck.ok) {
68
+ const body = await selfCheck.json().catch(() => ({}));
69
+ if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
70
+ console.warn(
71
+ `[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
72
+ );
73
+ } else if (debug) {
74
+ console.log("[VerificationGateway] API key self-check passed");
75
+ }
76
+ }
77
+ }
53
78
  } catch (err) {
54
79
  if (strictInit) {
55
80
  throw err;
@@ -167,8 +192,17 @@ function hasCredentials(credentials) {
167
192
  function createGuidanceResponse(_config, reason, options = {}) {
168
193
  const source = options.source ?? "no_credentials";
169
194
  const isApiError = source === "api_error";
195
+ const isMisconfig = source === "merchant_misconfig";
170
196
  const urls = options.urls;
171
- const guidance = isApiError ? {
197
+ const guidance = isMisconfig ? {
198
+ 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.",
199
+ registrationUrl: urls?.registrationUrl ?? "",
200
+ documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
201
+ steps: [
202
+ "Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
203
+ "Do not retry: the failure is deterministic until the operator updates their key"
204
+ ]
205
+ } : isApiError ? {
172
206
  message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
173
207
  registrationUrl: urls?.registrationUrl ?? "",
174
208
  documentationUrl: urls?.documentationUrl ?? "",
@@ -206,14 +240,24 @@ function createGuidanceResponse(_config, reason, options = {}) {
206
240
  // partners (and their custom onDenied handlers) can branch on
207
241
  // dimension. Without this, the synthesised stub was indistinguishable
208
242
  // from a real policy deny.
209
- failures: isApiError ? [
243
+ failures: isMisconfig ? [
244
+ {
245
+ dimension: "verify_access.merchant_misconfigured",
246
+ message: reason ?? "The integration API key was rejected by AstraSync",
247
+ guidance: guidance.message
248
+ }
249
+ ] : isApiError ? [
210
250
  {
211
251
  dimension: "verify_access.api_error",
212
252
  message: reason ?? "Verification temporarily unavailable",
213
253
  guidance: guidance.message
214
254
  }
215
255
  ] : void 0,
256
+ // 4.0.0: typed marker so adapters render the misconfig envelope (503 +
257
+ // MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
258
+ ...isMisconfig && { misconfigured: true },
216
259
  correlationId: options.correlationId,
260
+ attemptId: options.attemptId,
217
261
  verifiedAt: /* @__PURE__ */ new Date()
218
262
  };
219
263
  }
@@ -243,6 +287,8 @@ async function callVerifyAccessAPI(config, request) {
243
287
  body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
244
288
  if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
245
289
  if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
290
+ if (requestData.attemptId) body.attemptId = requestData.attemptId;
291
+ if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
246
292
  body.sdkVersion = SDK_VERSION;
247
293
  if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
248
294
  const meta = {
@@ -264,12 +310,16 @@ async function callVerifyAccessAPI(config, request) {
264
310
  const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
265
311
  method: "POST",
266
312
  headers,
267
- body: JSON.stringify(body)
313
+ body: JSON.stringify(body),
314
+ signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
268
315
  });
269
316
  const data = await response.json();
270
317
  if (response.status === 410) {
271
318
  return {
272
319
  success: true,
320
+ // 3.12.0 (Trust Record): keep the server-echoed attempt handle even on
321
+ // the synthesised 410 deny shape (echoed on every branch).
322
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
273
323
  access: {
274
324
  allowed: false,
275
325
  accessLevel: "none",
@@ -285,10 +335,22 @@ async function callVerifyAccessAPI(config, request) {
285
335
  };
286
336
  }
287
337
  if (!response.ok) {
338
+ if (response.status === 401) {
339
+ return {
340
+ success: false,
341
+ error: data.message || data.error || "Integration API key rejected",
342
+ misconfig: true,
343
+ misconfigCode: typeof data?.code === "string" ? data.code : void 0,
344
+ remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
345
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
346
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
347
+ };
348
+ }
288
349
  return {
289
350
  success: false,
290
351
  error: data.message || data.error || `API returned ${response.status}`,
291
- correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0
352
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
353
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
292
354
  };
293
355
  }
294
356
  return data;
@@ -305,9 +367,19 @@ async function verify(config, request, options) {
305
367
  const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
306
368
  if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
307
369
  if (mergedConfig.strictInit) {
308
- await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
370
+ await performInitCheck(
371
+ mergedConfig.apiBaseUrl,
372
+ mergedConfig.debug,
373
+ true,
374
+ mergedConfig.apiKey
375
+ );
309
376
  } else {
310
- void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, false);
377
+ void performInitCheck(
378
+ mergedConfig.apiBaseUrl,
379
+ mergedConfig.debug,
380
+ false,
381
+ mergedConfig.apiKey
382
+ );
311
383
  }
312
384
  }
313
385
  if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
@@ -322,7 +394,13 @@ async function verify(config, request, options) {
322
394
  if (mergedConfig.debug) {
323
395
  console.log("[VerificationGateway] Returning cached result");
324
396
  }
325
- return cached;
397
+ const hit = { ...cached };
398
+ if (request.attemptId) {
399
+ hit.attemptId = request.attemptId;
400
+ } else {
401
+ delete hit.attemptId;
402
+ }
403
+ return hit;
326
404
  }
327
405
  }
328
406
  const enrichedRequest = { ...request };
@@ -340,8 +418,10 @@ async function verify(config, request, options) {
340
418
  const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
341
419
  if (!apiResponse.success) {
342
420
  return createGuidanceResponse(mergedConfig, apiResponse.error, {
343
- source: "api_error",
421
+ source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
344
422
  correlationId: apiResponse.correlationId,
423
+ attemptId: apiResponse.attemptId,
424
+ remediation: apiResponse.remediation,
345
425
  urls
346
426
  });
347
427
  }
@@ -377,6 +457,9 @@ async function verify(config, request, options) {
377
457
  // Anonymous traffic has no session → correlationId is the per-attempt
378
458
  // linking key (the sessionId-equivalent for anonymous callers).
379
459
  correlationId: apiResponse.correlationId,
460
+ // 3.12.0 (Trust Record): server echoes the attempt-chain handle on
461
+ // every branch — denials included (the funnel outlives one deny).
462
+ attemptId: apiResponse.attemptId,
380
463
  recommendation: apiResponse.recommendation,
381
464
  recommendationReasons: apiResponse.recommendationReasons,
382
465
  stepUpApproval: apiResponse.stepUpApproval,
@@ -428,6 +511,8 @@ async function verify(config, request, options) {
428
511
  // v2.3.10 (defect #34, round-4): anonymous responses surface correlationId
429
512
  // (no session row exists for unverified callers).
430
513
  correlationId: apiResponse.correlationId,
514
+ // 3.12.0 (Trust Record): server-echoed attempt-chain handle.
515
+ attemptId: apiResponse.attemptId,
431
516
  runtimeChallenge: apiResponse.runtimeChallenge,
432
517
  tokenGuidance: apiResponse.tokenGuidance,
433
518
  recommendation: apiResponse.recommendation,
@@ -472,6 +557,24 @@ async function recordDecision(config, sessionId, decision, reason) {
472
557
  }).catch(() => {
473
558
  });
474
559
  }
560
+ async function reportAttempt(config, report) {
561
+ const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
562
+ const headers = { "Content-Type": "application/json" };
563
+ if (config.apiKey) {
564
+ headers["Authorization"] = `Bearer ${config.apiKey}`;
565
+ headers["X-API-Key"] = config.apiKey;
566
+ }
567
+ const body = {
568
+ ...report,
569
+ ...!report.counterpartyId && config.counterpartyId && { counterpartyId: config.counterpartyId }
570
+ };
571
+ await fetch(`${apiBaseUrl}/agents/verify-access/attempt-report`, {
572
+ method: "POST",
573
+ headers,
574
+ body: JSON.stringify(body)
575
+ }).catch(() => {
576
+ });
577
+ }
475
578
  async function fetchRoutes(config, counterpartyId) {
476
579
  if (!counterpartyId) return null;
477
580
  const headers = { "Content-Type": "application/json" };
@@ -543,12 +646,14 @@ async function quickVerify(config, credentials) {
543
646
  };
544
647
  }
545
648
  export {
649
+ _resetInitCheck,
546
650
  clearCache,
547
651
  extractCredentials,
548
652
  fetchRoutes,
549
653
  hasCredentials,
550
654
  quickVerify,
551
655
  recordDecision,
656
+ reportAttempt,
552
657
  reportCounterpartyPreCheckFailure,
553
658
  reportUnregisteredAttempt,
554
659
  verify,