@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
@@ -1,4 +1,4 @@
1
1
  import 'next/server';
2
- import '../types-sy3tq8lp.mjs';
3
- export { c as createMatcherConfig, a as createMiddleware } from '../nextjs-DcQIk6Zj.mjs';
2
+ import '../types-BcDf9Kk0.mjs';
3
+ export { c as createMatcherConfig, a as createMiddleware } from '../nextjs-DeUTnOBd.mjs';
4
4
  import '../metadata-capture.mjs';
@@ -1,4 +1,4 @@
1
1
  import 'next/server';
2
- import '../types-9tns4wyl.js';
3
- export { c as createMatcherConfig, a as createMiddleware } from '../nextjs-CEBVBsdi.js';
2
+ import '../types-fTQD448H.js';
3
+ export { c as createMatcherConfig, a as createMiddleware } from '../nextjs-D_iFf5k-.js';
4
4
  import '../metadata-capture.js';
@@ -102,7 +102,7 @@ function getTrustLevel(score) {
102
102
  }
103
103
 
104
104
  // src/version.ts
105
- var SDK_VERSION = "3.11.1";
105
+ var SDK_VERSION = "4.0.0";
106
106
 
107
107
  // src/well-known.ts
108
108
  var CACHE_TTL_MS = 60 * 60 * 1e3;
@@ -128,7 +128,7 @@ var DEFAULT_CONFIG = {
128
128
  };
129
129
  var initCheckPerformed = false;
130
130
  var deprecationWarningShown = false;
131
- async function performInitCheck(apiBaseUrl, debug, strictInit) {
131
+ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
132
132
  initCheckPerformed = true;
133
133
  try {
134
134
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
@@ -145,6 +145,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
145
145
  `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
146
146
  );
147
147
  }
148
+ if (apiKey) {
149
+ const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
150
+ headers: { Authorization: `Bearer ${apiKey}` }
151
+ });
152
+ if (selfCheck.status === 401) {
153
+ const body = await selfCheck.json().catch(() => ({}));
154
+ 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}` : "") + `.`;
155
+ if (strictInit) {
156
+ throw new Error(`${message} (strictInit=true)`);
157
+ }
158
+ console.error(message);
159
+ } else if (selfCheck.ok) {
160
+ const body = await selfCheck.json().catch(() => ({}));
161
+ if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
162
+ console.warn(
163
+ `[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
164
+ );
165
+ } else if (debug) {
166
+ console.log("[VerificationGateway] API key self-check passed");
167
+ }
168
+ }
169
+ }
148
170
  } catch (err) {
149
171
  if (strictInit) {
150
172
  throw err;
@@ -222,8 +244,17 @@ function cacheResult(request, result, configuredTtl, counterpartyId) {
222
244
  function createGuidanceResponse(_config, reason, options = {}) {
223
245
  const source = options.source ?? "no_credentials";
224
246
  const isApiError = source === "api_error";
247
+ const isMisconfig = source === "merchant_misconfig";
225
248
  const urls = options.urls;
226
- const guidance = isApiError ? {
249
+ const guidance = isMisconfig ? {
250
+ 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.",
251
+ registrationUrl: urls?.registrationUrl ?? "",
252
+ documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
253
+ steps: [
254
+ "Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
255
+ "Do not retry: the failure is deterministic until the operator updates their key"
256
+ ]
257
+ } : isApiError ? {
227
258
  message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
228
259
  registrationUrl: urls?.registrationUrl ?? "",
229
260
  documentationUrl: urls?.documentationUrl ?? "",
@@ -261,14 +292,24 @@ function createGuidanceResponse(_config, reason, options = {}) {
261
292
  // partners (and their custom onDenied handlers) can branch on
262
293
  // dimension. Without this, the synthesised stub was indistinguishable
263
294
  // from a real policy deny.
264
- failures: isApiError ? [
295
+ failures: isMisconfig ? [
296
+ {
297
+ dimension: "verify_access.merchant_misconfigured",
298
+ message: reason ?? "The integration API key was rejected by AstraSync",
299
+ guidance: guidance.message
300
+ }
301
+ ] : isApiError ? [
265
302
  {
266
303
  dimension: "verify_access.api_error",
267
304
  message: reason ?? "Verification temporarily unavailable",
268
305
  guidance: guidance.message
269
306
  }
270
307
  ] : void 0,
308
+ // 4.0.0: typed marker so adapters render the misconfig envelope (503 +
309
+ // MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
310
+ ...isMisconfig && { misconfigured: true },
271
311
  correlationId: options.correlationId,
312
+ attemptId: options.attemptId,
272
313
  verifiedAt: /* @__PURE__ */ new Date()
273
314
  };
274
315
  }
@@ -298,6 +339,8 @@ async function callVerifyAccessAPI(config, request) {
298
339
  body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
299
340
  if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
300
341
  if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
342
+ if (requestData.attemptId) body.attemptId = requestData.attemptId;
343
+ if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
301
344
  body.sdkVersion = SDK_VERSION;
302
345
  if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
303
346
  const meta = {
@@ -319,12 +362,16 @@ async function callVerifyAccessAPI(config, request) {
319
362
  const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
320
363
  method: "POST",
321
364
  headers,
322
- body: JSON.stringify(body)
365
+ body: JSON.stringify(body),
366
+ signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
323
367
  });
324
368
  const data = await response.json();
325
369
  if (response.status === 410) {
326
370
  return {
327
371
  success: true,
372
+ // 3.12.0 (Trust Record): keep the server-echoed attempt handle even on
373
+ // the synthesised 410 deny shape (echoed on every branch).
374
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
328
375
  access: {
329
376
  allowed: false,
330
377
  accessLevel: "none",
@@ -340,10 +387,22 @@ async function callVerifyAccessAPI(config, request) {
340
387
  };
341
388
  }
342
389
  if (!response.ok) {
390
+ if (response.status === 401) {
391
+ return {
392
+ success: false,
393
+ error: data.message || data.error || "Integration API key rejected",
394
+ misconfig: true,
395
+ misconfigCode: typeof data?.code === "string" ? data.code : void 0,
396
+ remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
397
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
398
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
399
+ };
400
+ }
343
401
  return {
344
402
  success: false,
345
403
  error: data.message || data.error || `API returned ${response.status}`,
346
- correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0
404
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
405
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
347
406
  };
348
407
  }
349
408
  return data;
@@ -360,9 +419,19 @@ async function verify(config, request, options) {
360
419
  const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
361
420
  if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
362
421
  if (mergedConfig.strictInit) {
363
- await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
422
+ await performInitCheck(
423
+ mergedConfig.apiBaseUrl,
424
+ mergedConfig.debug,
425
+ true,
426
+ mergedConfig.apiKey
427
+ );
364
428
  } else {
365
- void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, false);
429
+ void performInitCheck(
430
+ mergedConfig.apiBaseUrl,
431
+ mergedConfig.debug,
432
+ false,
433
+ mergedConfig.apiKey
434
+ );
366
435
  }
367
436
  }
368
437
  if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
@@ -377,7 +446,13 @@ async function verify(config, request, options) {
377
446
  if (mergedConfig.debug) {
378
447
  console.log("[VerificationGateway] Returning cached result");
379
448
  }
380
- return cached;
449
+ const hit = { ...cached };
450
+ if (request.attemptId) {
451
+ hit.attemptId = request.attemptId;
452
+ } else {
453
+ delete hit.attemptId;
454
+ }
455
+ return hit;
381
456
  }
382
457
  }
383
458
  const enrichedRequest = { ...request };
@@ -395,8 +470,10 @@ async function verify(config, request, options) {
395
470
  const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
396
471
  if (!apiResponse.success) {
397
472
  return createGuidanceResponse(mergedConfig, apiResponse.error, {
398
- source: "api_error",
473
+ source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
399
474
  correlationId: apiResponse.correlationId,
475
+ attemptId: apiResponse.attemptId,
476
+ remediation: apiResponse.remediation,
400
477
  urls
401
478
  });
402
479
  }
@@ -432,6 +509,9 @@ async function verify(config, request, options) {
432
509
  // Anonymous traffic has no session → correlationId is the per-attempt
433
510
  // linking key (the sessionId-equivalent for anonymous callers).
434
511
  correlationId: apiResponse.correlationId,
512
+ // 3.12.0 (Trust Record): server echoes the attempt-chain handle on
513
+ // every branch — denials included (the funnel outlives one deny).
514
+ attemptId: apiResponse.attemptId,
435
515
  recommendation: apiResponse.recommendation,
436
516
  recommendationReasons: apiResponse.recommendationReasons,
437
517
  stepUpApproval: apiResponse.stepUpApproval,
@@ -483,6 +563,8 @@ async function verify(config, request, options) {
483
563
  // v2.3.10 (defect #34, round-4): anonymous responses surface correlationId
484
564
  // (no session row exists for unverified callers).
485
565
  correlationId: apiResponse.correlationId,
566
+ // 3.12.0 (Trust Record): server-echoed attempt-chain handle.
567
+ attemptId: apiResponse.attemptId,
486
568
  runtimeChallenge: apiResponse.runtimeChallenge,
487
569
  tokenGuidance: apiResponse.tokenGuidance,
488
570
  recommendation: apiResponse.recommendation,
@@ -1250,6 +1332,21 @@ function createMiddleware(options) {
1250
1332
  const approvalRequired = result.identityVerified && result.policyAllowed && requiresHumanApproval(result);
1251
1333
  if (approvalRequired) annotateApprovalRequired(result);
1252
1334
  if (!result.identityVerified || !result.policyAllowed || approvalRequired) {
1335
+ if (result.misconfigured && pathname.startsWith("/api/")) {
1336
+ return NextResponse.json(
1337
+ {
1338
+ success: false,
1339
+ error: {
1340
+ code: "MERCHANT_VERIFICATION_MISCONFIGURED",
1341
+ message: result.denialReasons?.[0] || "This site's AstraSync integration is misconfigured",
1342
+ guidance: result.guidance,
1343
+ failures: result.failures,
1344
+ correlationId: result.correlationId
1345
+ }
1346
+ },
1347
+ { status: 503 }
1348
+ );
1349
+ }
1253
1350
  if (pathname.startsWith("/api/")) {
1254
1351
  return NextResponse.json(
1255
1352
  {