@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
@@ -65,7 +65,7 @@ function getTrustLevel(score) {
65
65
  }
66
66
 
67
67
  // src/version.ts
68
- var SDK_VERSION = "3.11.1";
68
+ var SDK_VERSION = "4.0.0";
69
69
 
70
70
  // src/well-known.ts
71
71
  var CACHE_TTL_MS = 60 * 60 * 1e3;
@@ -91,7 +91,7 @@ var DEFAULT_CONFIG = {
91
91
  };
92
92
  var initCheckPerformed = false;
93
93
  var deprecationWarningShown = false;
94
- async function performInitCheck(apiBaseUrl, debug, strictInit) {
94
+ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
95
95
  initCheckPerformed = true;
96
96
  try {
97
97
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
@@ -108,6 +108,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
108
108
  `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
109
109
  );
110
110
  }
111
+ if (apiKey) {
112
+ const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
113
+ headers: { Authorization: `Bearer ${apiKey}` }
114
+ });
115
+ if (selfCheck.status === 401) {
116
+ const body = await selfCheck.json().catch(() => ({}));
117
+ 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}` : "") + `.`;
118
+ if (strictInit) {
119
+ throw new Error(`${message} (strictInit=true)`);
120
+ }
121
+ console.error(message);
122
+ } else if (selfCheck.ok) {
123
+ const body = await selfCheck.json().catch(() => ({}));
124
+ if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
125
+ console.warn(
126
+ `[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
127
+ );
128
+ } else if (debug) {
129
+ console.log("[VerificationGateway] API key self-check passed");
130
+ }
131
+ }
132
+ }
111
133
  } catch (err) {
112
134
  if (strictInit) {
113
135
  throw err;
@@ -185,8 +207,17 @@ function cacheResult(request, result, configuredTtl, counterpartyId) {
185
207
  function createGuidanceResponse(_config, reason, options = {}) {
186
208
  const source = options.source ?? "no_credentials";
187
209
  const isApiError = source === "api_error";
210
+ const isMisconfig = source === "merchant_misconfig";
188
211
  const urls = options.urls;
189
- const guidance = isApiError ? {
212
+ const guidance = isMisconfig ? {
213
+ 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.",
214
+ registrationUrl: urls?.registrationUrl ?? "",
215
+ documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
216
+ steps: [
217
+ "Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
218
+ "Do not retry: the failure is deterministic until the operator updates their key"
219
+ ]
220
+ } : isApiError ? {
190
221
  message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
191
222
  registrationUrl: urls?.registrationUrl ?? "",
192
223
  documentationUrl: urls?.documentationUrl ?? "",
@@ -224,14 +255,24 @@ function createGuidanceResponse(_config, reason, options = {}) {
224
255
  // partners (and their custom onDenied handlers) can branch on
225
256
  // dimension. Without this, the synthesised stub was indistinguishable
226
257
  // from a real policy deny.
227
- failures: isApiError ? [
258
+ failures: isMisconfig ? [
259
+ {
260
+ dimension: "verify_access.merchant_misconfigured",
261
+ message: reason ?? "The integration API key was rejected by AstraSync",
262
+ guidance: guidance.message
263
+ }
264
+ ] : isApiError ? [
228
265
  {
229
266
  dimension: "verify_access.api_error",
230
267
  message: reason ?? "Verification temporarily unavailable",
231
268
  guidance: guidance.message
232
269
  }
233
270
  ] : void 0,
271
+ // 4.0.0: typed marker so adapters render the misconfig envelope (503 +
272
+ // MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
273
+ ...isMisconfig && { misconfigured: true },
234
274
  correlationId: options.correlationId,
275
+ attemptId: options.attemptId,
235
276
  verifiedAt: /* @__PURE__ */ new Date()
236
277
  };
237
278
  }
@@ -261,6 +302,8 @@ async function callVerifyAccessAPI(config, request) {
261
302
  body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
262
303
  if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
263
304
  if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
305
+ if (requestData.attemptId) body.attemptId = requestData.attemptId;
306
+ if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
264
307
  body.sdkVersion = SDK_VERSION;
265
308
  if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
266
309
  const meta = {
@@ -282,12 +325,16 @@ async function callVerifyAccessAPI(config, request) {
282
325
  const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
283
326
  method: "POST",
284
327
  headers,
285
- body: JSON.stringify(body)
328
+ body: JSON.stringify(body),
329
+ signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
286
330
  });
287
331
  const data = await response.json();
288
332
  if (response.status === 410) {
289
333
  return {
290
334
  success: true,
335
+ // 3.12.0 (Trust Record): keep the server-echoed attempt handle even on
336
+ // the synthesised 410 deny shape (echoed on every branch).
337
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
291
338
  access: {
292
339
  allowed: false,
293
340
  accessLevel: "none",
@@ -303,10 +350,22 @@ async function callVerifyAccessAPI(config, request) {
303
350
  };
304
351
  }
305
352
  if (!response.ok) {
353
+ if (response.status === 401) {
354
+ return {
355
+ success: false,
356
+ error: data.message || data.error || "Integration API key rejected",
357
+ misconfig: true,
358
+ misconfigCode: typeof data?.code === "string" ? data.code : void 0,
359
+ remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
360
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
361
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
362
+ };
363
+ }
306
364
  return {
307
365
  success: false,
308
366
  error: data.message || data.error || `API returned ${response.status}`,
309
- correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0
367
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
368
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
310
369
  };
311
370
  }
312
371
  return data;
@@ -323,9 +382,19 @@ async function verify(config, request, options) {
323
382
  const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
324
383
  if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
325
384
  if (mergedConfig.strictInit) {
326
- await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
385
+ await performInitCheck(
386
+ mergedConfig.apiBaseUrl,
387
+ mergedConfig.debug,
388
+ true,
389
+ mergedConfig.apiKey
390
+ );
327
391
  } else {
328
- void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, false);
392
+ void performInitCheck(
393
+ mergedConfig.apiBaseUrl,
394
+ mergedConfig.debug,
395
+ false,
396
+ mergedConfig.apiKey
397
+ );
329
398
  }
330
399
  }
331
400
  if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
@@ -340,7 +409,13 @@ async function verify(config, request, options) {
340
409
  if (mergedConfig.debug) {
341
410
  console.log("[VerificationGateway] Returning cached result");
342
411
  }
343
- return cached;
412
+ const hit = { ...cached };
413
+ if (request.attemptId) {
414
+ hit.attemptId = request.attemptId;
415
+ } else {
416
+ delete hit.attemptId;
417
+ }
418
+ return hit;
344
419
  }
345
420
  }
346
421
  const enrichedRequest = { ...request };
@@ -358,8 +433,10 @@ async function verify(config, request, options) {
358
433
  const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
359
434
  if (!apiResponse.success) {
360
435
  return createGuidanceResponse(mergedConfig, apiResponse.error, {
361
- source: "api_error",
436
+ source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
362
437
  correlationId: apiResponse.correlationId,
438
+ attemptId: apiResponse.attemptId,
439
+ remediation: apiResponse.remediation,
363
440
  urls
364
441
  });
365
442
  }
@@ -395,6 +472,9 @@ async function verify(config, request, options) {
395
472
  // Anonymous traffic has no session → correlationId is the per-attempt
396
473
  // linking key (the sessionId-equivalent for anonymous callers).
397
474
  correlationId: apiResponse.correlationId,
475
+ // 3.12.0 (Trust Record): server echoes the attempt-chain handle on
476
+ // every branch — denials included (the funnel outlives one deny).
477
+ attemptId: apiResponse.attemptId,
398
478
  recommendation: apiResponse.recommendation,
399
479
  recommendationReasons: apiResponse.recommendationReasons,
400
480
  stepUpApproval: apiResponse.stepUpApproval,
@@ -446,6 +526,8 @@ async function verify(config, request, options) {
446
526
  // v2.3.10 (defect #34, round-4): anonymous responses surface correlationId
447
527
  // (no session row exists for unverified callers).
448
528
  correlationId: apiResponse.correlationId,
529
+ // 3.12.0 (Trust Record): server-echoed attempt-chain handle.
530
+ attemptId: apiResponse.attemptId,
449
531
  runtimeChallenge: apiResponse.runtimeChallenge,
450
532
  tokenGuidance: apiResponse.tokenGuidance,
451
533
  recommendation: apiResponse.recommendation,
@@ -1213,6 +1295,21 @@ function createMiddleware(options) {
1213
1295
  const approvalRequired = result.identityVerified && result.policyAllowed && requiresHumanApproval(result);
1214
1296
  if (approvalRequired) annotateApprovalRequired(result);
1215
1297
  if (!result.identityVerified || !result.policyAllowed || approvalRequired) {
1298
+ if (result.misconfigured && pathname.startsWith("/api/")) {
1299
+ return NextResponse.json(
1300
+ {
1301
+ success: false,
1302
+ error: {
1303
+ code: "MERCHANT_VERIFICATION_MISCONFIGURED",
1304
+ message: result.denialReasons?.[0] || "This site's AstraSync integration is misconfigured",
1305
+ guidance: result.guidance,
1306
+ failures: result.failures,
1307
+ correlationId: result.correlationId
1308
+ }
1309
+ },
1310
+ { status: 503 }
1311
+ );
1312
+ }
1216
1313
  if (pathname.startsWith("/api/")) {
1217
1314
  return NextResponse.json(
1218
1315
  {