@astrasyncai/verification-gateway 3.12.0 → 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 +85 -8
  6. package/dist/adapters/express.js.map +1 -1
  7. package/dist/adapters/express.mjs +85 -8
  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 +90 -8
  12. package/dist/adapters/mcp.js.map +1 -1
  13. package/dist/adapters/mcp.mjs +90 -8
  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 +86 -8
  18. package/dist/adapters/nextjs.js.map +1 -1
  19. package/dist/adapters/nextjs.mjs +86 -8
  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 +71 -8
  24. package/dist/adapters/sdk.js.map +1 -1
  25. package/dist/adapters/sdk.mjs +71 -8
  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 +71 -8
  30. package/dist/bin/astrasync-codex-hook.js +71 -8
  31. package/dist/bin/astrasync-guard.js +71 -8
  32. package/dist/bin/astrasync.js +71 -8
  33. package/dist/browser/background.js +71 -8
  34. package/dist/browser/background.js.map +1 -1
  35. package/dist/browser/background.mjs +71 -8
  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 +71 -8
  46. package/dist/codex/index.js.map +1 -1
  47. package/dist/codex/index.mjs +71 -8
  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 +71 -8
  54. package/dist/cursor/extension.js.map +1 -1
  55. package/dist/cursor/extension.mjs +71 -8
  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-B39o89gf.d.mts → express-BZajRs4i.d.mts} +1 -1
  60. package/dist/{express-BuxKNO_q.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 +71 -8
  64. package/dist/gateway/gateway.js.map +1 -1
  65. package/dist/gateway/gateway.mjs +71 -8
  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-DME3w3lf.d.mts → index-B0cyMZDL.d.mts} +1 -1
  70. package/dist/{index-CqydB4ks.d.mts → index-BRYteOqO.d.mts} +1 -1
  71. package/dist/{index-BG62SXso.d.ts → index-BZQdVqNw.d.ts} +1 -1
  72. package/dist/{index-CLHdqs2M.d.ts → index-adgKhujR.d.ts} +1 -1
  73. package/dist/index.d.mts +8 -8
  74. package/dist/index.d.ts +8 -8
  75. package/dist/index.js +119 -8
  76. package/dist/index.js.map +1 -1
  77. package/dist/index.mjs +119 -8
  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-Ddlw_J1J.d.ts → nextjs-D_iFf5k-.d.ts} +1 -1
  82. package/dist/{nextjs-D74W7wt-.d.mts → nextjs-DeUTnOBd.d.mts} +1 -1
  83. package/dist/{sdk-CT7gdkfR.d.ts → sdk-BM3mwEAq.d.ts} +1 -1
  84. package/dist/{sdk-Bn6bj7kt.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-BntuzEEn.d.mts → types-BcDf9Kk0.d.mts} +15 -0
  88. package/dist/{types-DHu7m9HI.d.ts → types-CHKCgDFC.d.ts} +1 -1
  89. package/dist/{types-Djw4GLtz.d.mts → types-DfnP7JiM.d.mts} +1 -1
  90. package/dist/{types-SDu4Llbe.d.ts → types-fTQD448H.d.ts} +15 -0
  91. package/dist/ui/index.d.mts +1 -1
  92. package/dist/ui/index.d.ts +1 -1
  93. package/dist/verify.d.mts +4 -2
  94. package/dist/verify.d.ts +4 -2
  95. package/dist/verify.js +76 -8
  96. package/dist/verify.js.map +1 -1
  97. package/dist/verify.mjs +75 -8
  98. package/dist/verify.mjs.map +1 -1
  99. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -126,7 +126,7 @@ function getCapabilities(accessLevel) {
126
126
  }
127
127
 
128
128
  // src/version.ts
129
- var SDK_VERSION = "3.12.0";
129
+ var SDK_VERSION = "4.0.0";
130
130
 
131
131
  // src/well-known.ts
132
132
  var CACHE_TTL_MS = 60 * 60 * 1e3;
@@ -204,7 +204,7 @@ var DEFAULT_CONFIG = {
204
204
  };
205
205
  var initCheckPerformed = false;
206
206
  var deprecationWarningShown = false;
207
- async function performInitCheck(apiBaseUrl, debug, strictInit) {
207
+ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
208
208
  initCheckPerformed = true;
209
209
  try {
210
210
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
@@ -221,6 +221,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
221
221
  `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
222
222
  );
223
223
  }
224
+ if (apiKey) {
225
+ const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
226
+ headers: { Authorization: `Bearer ${apiKey}` }
227
+ });
228
+ if (selfCheck.status === 401) {
229
+ const body = await selfCheck.json().catch(() => ({}));
230
+ 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}` : "") + `.`;
231
+ if (strictInit) {
232
+ throw new Error(`${message} (strictInit=true)`);
233
+ }
234
+ console.error(message);
235
+ } else if (selfCheck.ok) {
236
+ const body = await selfCheck.json().catch(() => ({}));
237
+ if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
238
+ console.warn(
239
+ `[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
240
+ );
241
+ } else if (debug) {
242
+ console.log("[VerificationGateway] API key self-check passed");
243
+ }
244
+ }
245
+ }
224
246
  } catch (err) {
225
247
  if (strictInit) {
226
248
  throw err;
@@ -338,8 +360,17 @@ function hasCredentials(credentials) {
338
360
  function createGuidanceResponse(_config, reason, options = {}) {
339
361
  const source = options.source ?? "no_credentials";
340
362
  const isApiError = source === "api_error";
363
+ const isMisconfig = source === "merchant_misconfig";
341
364
  const urls = options.urls;
342
- const guidance = isApiError ? {
365
+ const guidance = isMisconfig ? {
366
+ 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.",
367
+ registrationUrl: urls?.registrationUrl ?? "",
368
+ documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
369
+ steps: [
370
+ "Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
371
+ "Do not retry: the failure is deterministic until the operator updates their key"
372
+ ]
373
+ } : isApiError ? {
343
374
  message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
344
375
  registrationUrl: urls?.registrationUrl ?? "",
345
376
  documentationUrl: urls?.documentationUrl ?? "",
@@ -377,13 +408,22 @@ function createGuidanceResponse(_config, reason, options = {}) {
377
408
  // partners (and their custom onDenied handlers) can branch on
378
409
  // dimension. Without this, the synthesised stub was indistinguishable
379
410
  // from a real policy deny.
380
- failures: isApiError ? [
411
+ failures: isMisconfig ? [
412
+ {
413
+ dimension: "verify_access.merchant_misconfigured",
414
+ message: reason ?? "The integration API key was rejected by AstraSync",
415
+ guidance: guidance.message
416
+ }
417
+ ] : isApiError ? [
381
418
  {
382
419
  dimension: "verify_access.api_error",
383
420
  message: reason ?? "Verification temporarily unavailable",
384
421
  guidance: guidance.message
385
422
  }
386
423
  ] : void 0,
424
+ // 4.0.0: typed marker so adapters render the misconfig envelope (503 +
425
+ // MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
426
+ ...isMisconfig && { misconfigured: true },
387
427
  correlationId: options.correlationId,
388
428
  attemptId: options.attemptId,
389
429
  verifiedAt: /* @__PURE__ */ new Date()
@@ -438,7 +478,8 @@ async function callVerifyAccessAPI(config, request) {
438
478
  const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
439
479
  method: "POST",
440
480
  headers,
441
- body: JSON.stringify(body)
481
+ body: JSON.stringify(body),
482
+ signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
442
483
  });
443
484
  const data = await response.json();
444
485
  if (response.status === 410) {
@@ -462,6 +503,17 @@ async function callVerifyAccessAPI(config, request) {
462
503
  };
463
504
  }
464
505
  if (!response.ok) {
506
+ if (response.status === 401) {
507
+ return {
508
+ success: false,
509
+ error: data.message || data.error || "Integration API key rejected",
510
+ misconfig: true,
511
+ misconfigCode: typeof data?.code === "string" ? data.code : void 0,
512
+ remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
513
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
514
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
515
+ };
516
+ }
465
517
  return {
466
518
  success: false,
467
519
  error: data.message || data.error || `API returned ${response.status}`,
@@ -483,9 +535,19 @@ async function verify(config, request, options) {
483
535
  const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
484
536
  if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
485
537
  if (mergedConfig.strictInit) {
486
- await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
538
+ await performInitCheck(
539
+ mergedConfig.apiBaseUrl,
540
+ mergedConfig.debug,
541
+ true,
542
+ mergedConfig.apiKey
543
+ );
487
544
  } else {
488
- void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, false);
545
+ void performInitCheck(
546
+ mergedConfig.apiBaseUrl,
547
+ mergedConfig.debug,
548
+ false,
549
+ mergedConfig.apiKey
550
+ );
489
551
  }
490
552
  }
491
553
  if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
@@ -524,9 +586,10 @@ async function verify(config, request, options) {
524
586
  const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
525
587
  if (!apiResponse.success) {
526
588
  return createGuidanceResponse(mergedConfig, apiResponse.error, {
527
- source: "api_error",
589
+ source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
528
590
  correlationId: apiResponse.correlationId,
529
591
  attemptId: apiResponse.attemptId,
592
+ remediation: apiResponse.remediation,
530
593
  urls
531
594
  });
532
595
  }
@@ -1274,6 +1337,20 @@ function dedupeFailures(result) {
1274
1337
  }
1275
1338
  }
1276
1339
  function defaultOnDenied(result, _req, res) {
1340
+ if (result.misconfigured) {
1341
+ res.setHeader("X-Astra-Gateway-Mode", "enforced");
1342
+ res.status(503).json({
1343
+ success: false,
1344
+ error: {
1345
+ code: "MERCHANT_VERIFICATION_MISCONFIGURED",
1346
+ message: result.denialReasons?.[0] || "This site's AstraSync integration is misconfigured",
1347
+ guidance: result.guidance,
1348
+ failures: result.failures,
1349
+ correlationId: result.correlationId
1350
+ }
1351
+ });
1352
+ return;
1353
+ }
1277
1354
  const statusCode = !result.identityVerified ? 401 : 403;
1278
1355
  res.setHeader("X-Astra-Gateway-Mode", "enforced");
1279
1356
  res.status(statusCode).json({
@@ -1990,6 +2067,21 @@ function createMiddleware2(options) {
1990
2067
  const approvalRequired = result.identityVerified && result.policyAllowed && requiresHumanApproval(result);
1991
2068
  if (approvalRequired) annotateApprovalRequired(result);
1992
2069
  if (!result.identityVerified || !result.policyAllowed || approvalRequired) {
2070
+ if (result.misconfigured && pathname.startsWith("/api/")) {
2071
+ return NextResponse.json(
2072
+ {
2073
+ success: false,
2074
+ error: {
2075
+ code: "MERCHANT_VERIFICATION_MISCONFIGURED",
2076
+ message: result.denialReasons?.[0] || "This site's AstraSync integration is misconfigured",
2077
+ guidance: result.guidance,
2078
+ failures: result.failures,
2079
+ correlationId: result.correlationId
2080
+ }
2081
+ },
2082
+ { status: 503 }
2083
+ );
2084
+ }
1993
2085
  if (pathname.startsWith("/api/")) {
1994
2086
  return NextResponse.json(
1995
2087
  {
@@ -4916,6 +5008,24 @@ function dedupeFailures2(result) {
4916
5008
  }
4917
5009
  function defaultMcpDenied(result, req, res) {
4918
5010
  const id = req.body?.id ?? null;
5011
+ if (result.misconfigured) {
5012
+ res.setHeader("X-Astra-Gateway-Mode", "enforced");
5013
+ res.status(503).json({
5014
+ jsonrpc: "2.0",
5015
+ id,
5016
+ error: {
5017
+ // -32002 → merchant verification misconfigured (see -32000/-32001 below)
5018
+ code: -32002,
5019
+ message: result.denialReasons?.[0] ?? "This server's AstraSync integration is misconfigured",
5020
+ data: {
5021
+ guidance: result.guidance,
5022
+ failures: result.failures,
5023
+ correlationId: result.correlationId
5024
+ }
5025
+ }
5026
+ });
5027
+ return;
5028
+ }
4919
5029
  const status = !result.identityVerified ? 401 : 403;
4920
5030
  res.setHeader("X-Astra-Gateway-Mode", "enforced");
4921
5031
  res.status(status).json({
@@ -4925,6 +5035,7 @@ function defaultMcpDenied(result, req, res) {
4925
5035
  // JSON-RPC error codes:
4926
5036
  // -32000 → unauthorized (no identity resolved)
4927
5037
  // -32001 → insufficient access (identity OK, policy denied)
5038
+ // -32002 → merchant verification misconfigured (handled above)
4928
5039
  code: !result.identityVerified ? -32e3 : -32001,
4929
5040
  message: result.denialReasons?.[0] ?? "Access denied",
4930
5041
  data: {