@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.
- package/dist/adapter-interface/interface.d.mts +2 -2
- package/dist/adapter-interface/interface.d.ts +2 -2
- package/dist/adapters/express.d.mts +2 -2
- package/dist/adapters/express.d.ts +2 -2
- package/dist/adapters/express.js +106 -10
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +106 -10
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +1 -1
- package/dist/adapters/mcp.d.ts +1 -1
- package/dist/adapters/mcp.js +111 -10
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +111 -10
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +2 -2
- package/dist/adapters/nextjs.d.ts +2 -2
- package/dist/adapters/nextjs.js +107 -10
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +107 -10
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +2 -2
- package/dist/adapters/sdk.d.ts +2 -2
- package/dist/adapters/sdk.js +92 -10
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +92 -10
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.d.mts +2 -2
- package/dist/agent/index.d.ts +2 -2
- package/dist/bin/astrasync-claude-hook.js +92 -10
- package/dist/bin/astrasync-codex-hook.js +92 -10
- package/dist/bin/astrasync-guard.js +92 -10
- package/dist/bin/astrasync.js +93 -10
- package/dist/browser/background.js +92 -10
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +92 -10
- package/dist/browser/background.mjs.map +1 -1
- package/dist/browser/browser-adapter.d.mts +2 -2
- package/dist/browser/browser-adapter.d.ts +2 -2
- package/dist/claude-code/claude-code-adapter.d.mts +2 -2
- package/dist/claude-code/claude-code-adapter.d.ts +2 -2
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/codex/index.d.mts +2 -2
- package/dist/codex/index.d.ts +2 -2
- package/dist/codex/index.js +92 -10
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +92 -10
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/cursor-adapter.d.mts +2 -2
- package/dist/cursor/cursor-adapter.d.ts +2 -2
- package/dist/cursor/extension.d.mts +2 -2
- package/dist/cursor/extension.d.ts +2 -2
- package/dist/cursor/extension.js +92 -10
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +92 -10
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +1 -1
- package/dist/edge-config.d.ts +1 -1
- package/dist/{express-DCXa1oqj.d.mts → express-BZajRs4i.d.mts} +1 -1
- package/dist/{express-ClNtDhhc.d.ts → express-CjCUB1k7.d.ts} +1 -1
- package/dist/gateway/gateway.d.mts +2 -2
- package/dist/gateway/gateway.d.ts +2 -2
- package/dist/gateway/gateway.js +92 -10
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +92 -10
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +2 -2
- package/dist/git-trigger/git-hooks.d.ts +2 -2
- package/dist/{index-BrNKDmiR.d.mts → index-B0cyMZDL.d.mts} +1 -1
- package/dist/{index-Dr_XiN65.d.mts → index-BRYteOqO.d.mts} +1 -1
- package/dist/{index-CfHurO1P.d.ts → index-BZQdVqNw.d.ts} +1 -1
- package/dist/{index-D2ztkumS.d.ts → index-adgKhujR.d.ts} +1 -1
- package/dist/index.d.mts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +160 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +159 -10
- package/dist/index.mjs.map +1 -1
- package/dist/local-evaluator/evaluator.d.mts +2 -2
- package/dist/local-evaluator/evaluator.d.ts +2 -2
- package/dist/{nextjs-CEBVBsdi.d.ts → nextjs-D_iFf5k-.d.ts} +1 -1
- package/dist/{nextjs-DcQIk6Zj.d.mts → nextjs-DeUTnOBd.d.mts} +1 -1
- package/dist/{sdk-H0JCLW2y.d.ts → sdk-BM3mwEAq.d.ts} +1 -1
- package/dist/{sdk-CZkbSOeO.d.mts → sdk-_il1Q41f.d.mts} +1 -1
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/{types-sy3tq8lp.d.mts → types-BcDf9Kk0.d.mts} +118 -1
- package/dist/{types-DhFPiZ3t.d.ts → types-CHKCgDFC.d.ts} +1 -1
- package/dist/{types-cQVCMeNV.d.mts → types-DfnP7JiM.d.mts} +1 -1
- package/dist/{types-9tns4wyl.d.ts → types-fTQD448H.d.ts} +118 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +15 -2
- package/dist/verify.d.ts +15 -2
- package/dist/verify.js +117 -10
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +115 -10
- package/dist/verify.mjs.map +1 -1
- 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 = "
|
|
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 =
|
|
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,14 +408,24 @@ 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:
|
|
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,
|
|
428
|
+
attemptId: options.attemptId,
|
|
388
429
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
389
430
|
};
|
|
390
431
|
}
|
|
@@ -414,6 +455,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
414
455
|
body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
|
|
415
456
|
if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
|
|
416
457
|
if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
|
|
458
|
+
if (requestData.attemptId) body.attemptId = requestData.attemptId;
|
|
459
|
+
if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
|
|
417
460
|
body.sdkVersion = SDK_VERSION;
|
|
418
461
|
if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
|
|
419
462
|
const meta = {
|
|
@@ -435,12 +478,16 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
435
478
|
const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
436
479
|
method: "POST",
|
|
437
480
|
headers,
|
|
438
|
-
body: JSON.stringify(body)
|
|
481
|
+
body: JSON.stringify(body),
|
|
482
|
+
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
439
483
|
});
|
|
440
484
|
const data = await response.json();
|
|
441
485
|
if (response.status === 410) {
|
|
442
486
|
return {
|
|
443
487
|
success: true,
|
|
488
|
+
// 3.12.0 (Trust Record): keep the server-echoed attempt handle even on
|
|
489
|
+
// the synthesised 410 deny shape (echoed on every branch).
|
|
490
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
444
491
|
access: {
|
|
445
492
|
allowed: false,
|
|
446
493
|
accessLevel: "none",
|
|
@@ -456,10 +503,22 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
456
503
|
};
|
|
457
504
|
}
|
|
458
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
|
+
}
|
|
459
517
|
return {
|
|
460
518
|
success: false,
|
|
461
519
|
error: data.message || data.error || `API returned ${response.status}`,
|
|
462
|
-
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0
|
|
520
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
521
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
463
522
|
};
|
|
464
523
|
}
|
|
465
524
|
return data;
|
|
@@ -476,9 +535,19 @@ async function verify(config, request, options) {
|
|
|
476
535
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
477
536
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
478
537
|
if (mergedConfig.strictInit) {
|
|
479
|
-
await performInitCheck(
|
|
538
|
+
await performInitCheck(
|
|
539
|
+
mergedConfig.apiBaseUrl,
|
|
540
|
+
mergedConfig.debug,
|
|
541
|
+
true,
|
|
542
|
+
mergedConfig.apiKey
|
|
543
|
+
);
|
|
480
544
|
} else {
|
|
481
|
-
void performInitCheck(
|
|
545
|
+
void performInitCheck(
|
|
546
|
+
mergedConfig.apiBaseUrl,
|
|
547
|
+
mergedConfig.debug,
|
|
548
|
+
false,
|
|
549
|
+
mergedConfig.apiKey
|
|
550
|
+
);
|
|
482
551
|
}
|
|
483
552
|
}
|
|
484
553
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
@@ -493,7 +562,13 @@ async function verify(config, request, options) {
|
|
|
493
562
|
if (mergedConfig.debug) {
|
|
494
563
|
console.log("[VerificationGateway] Returning cached result");
|
|
495
564
|
}
|
|
496
|
-
|
|
565
|
+
const hit = { ...cached };
|
|
566
|
+
if (request.attemptId) {
|
|
567
|
+
hit.attemptId = request.attemptId;
|
|
568
|
+
} else {
|
|
569
|
+
delete hit.attemptId;
|
|
570
|
+
}
|
|
571
|
+
return hit;
|
|
497
572
|
}
|
|
498
573
|
}
|
|
499
574
|
const enrichedRequest = { ...request };
|
|
@@ -511,8 +586,10 @@ async function verify(config, request, options) {
|
|
|
511
586
|
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
512
587
|
if (!apiResponse.success) {
|
|
513
588
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
514
|
-
source: "api_error",
|
|
589
|
+
source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
|
|
515
590
|
correlationId: apiResponse.correlationId,
|
|
591
|
+
attemptId: apiResponse.attemptId,
|
|
592
|
+
remediation: apiResponse.remediation,
|
|
516
593
|
urls
|
|
517
594
|
});
|
|
518
595
|
}
|
|
@@ -548,6 +625,9 @@ async function verify(config, request, options) {
|
|
|
548
625
|
// Anonymous traffic has no session → correlationId is the per-attempt
|
|
549
626
|
// linking key (the sessionId-equivalent for anonymous callers).
|
|
550
627
|
correlationId: apiResponse.correlationId,
|
|
628
|
+
// 3.12.0 (Trust Record): server echoes the attempt-chain handle on
|
|
629
|
+
// every branch — denials included (the funnel outlives one deny).
|
|
630
|
+
attemptId: apiResponse.attemptId,
|
|
551
631
|
recommendation: apiResponse.recommendation,
|
|
552
632
|
recommendationReasons: apiResponse.recommendationReasons,
|
|
553
633
|
stepUpApproval: apiResponse.stepUpApproval,
|
|
@@ -599,6 +679,8 @@ async function verify(config, request, options) {
|
|
|
599
679
|
// v2.3.10 (defect #34, round-4): anonymous responses surface correlationId
|
|
600
680
|
// (no session row exists for unverified callers).
|
|
601
681
|
correlationId: apiResponse.correlationId,
|
|
682
|
+
// 3.12.0 (Trust Record): server-echoed attempt-chain handle.
|
|
683
|
+
attemptId: apiResponse.attemptId,
|
|
602
684
|
runtimeChallenge: apiResponse.runtimeChallenge,
|
|
603
685
|
tokenGuidance: apiResponse.tokenGuidance,
|
|
604
686
|
recommendation: apiResponse.recommendation,
|
|
@@ -643,6 +725,24 @@ async function recordDecision(config, sessionId, decision, reason) {
|
|
|
643
725
|
}).catch(() => {
|
|
644
726
|
});
|
|
645
727
|
}
|
|
728
|
+
async function reportAttempt(config, report) {
|
|
729
|
+
const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
|
|
730
|
+
const headers = { "Content-Type": "application/json" };
|
|
731
|
+
if (config.apiKey) {
|
|
732
|
+
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
733
|
+
headers["X-API-Key"] = config.apiKey;
|
|
734
|
+
}
|
|
735
|
+
const body = {
|
|
736
|
+
...report,
|
|
737
|
+
...!report.counterpartyId && config.counterpartyId && { counterpartyId: config.counterpartyId }
|
|
738
|
+
};
|
|
739
|
+
await fetch(`${apiBaseUrl}/agents/verify-access/attempt-report`, {
|
|
740
|
+
method: "POST",
|
|
741
|
+
headers,
|
|
742
|
+
body: JSON.stringify(body)
|
|
743
|
+
}).catch(() => {
|
|
744
|
+
});
|
|
745
|
+
}
|
|
646
746
|
async function fetchRoutes(config, counterpartyId) {
|
|
647
747
|
if (!counterpartyId) return null;
|
|
648
748
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -1237,6 +1337,20 @@ function dedupeFailures(result) {
|
|
|
1237
1337
|
}
|
|
1238
1338
|
}
|
|
1239
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
|
+
}
|
|
1240
1354
|
const statusCode = !result.identityVerified ? 401 : 403;
|
|
1241
1355
|
res.setHeader("X-Astra-Gateway-Mode", "enforced");
|
|
1242
1356
|
res.status(statusCode).json({
|
|
@@ -1953,6 +2067,21 @@ function createMiddleware2(options) {
|
|
|
1953
2067
|
const approvalRequired = result.identityVerified && result.policyAllowed && requiresHumanApproval(result);
|
|
1954
2068
|
if (approvalRequired) annotateApprovalRequired(result);
|
|
1955
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
|
+
}
|
|
1956
2085
|
if (pathname.startsWith("/api/")) {
|
|
1957
2086
|
return NextResponse.json(
|
|
1958
2087
|
{
|
|
@@ -4879,6 +5008,24 @@ function dedupeFailures2(result) {
|
|
|
4879
5008
|
}
|
|
4880
5009
|
function defaultMcpDenied(result, req, res) {
|
|
4881
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
|
+
}
|
|
4882
5029
|
const status = !result.identityVerified ? 401 : 403;
|
|
4883
5030
|
res.setHeader("X-Astra-Gateway-Mode", "enforced");
|
|
4884
5031
|
res.status(status).json({
|
|
@@ -4888,6 +5035,7 @@ function defaultMcpDenied(result, req, res) {
|
|
|
4888
5035
|
// JSON-RPC error codes:
|
|
4889
5036
|
// -32000 → unauthorized (no identity resolved)
|
|
4890
5037
|
// -32001 → insufficient access (identity OK, policy denied)
|
|
5038
|
+
// -32002 → merchant verification misconfigured (handled above)
|
|
4891
5039
|
code: !result.identityVerified ? -32e3 : -32001,
|
|
4892
5040
|
message: result.denialReasons?.[0] ?? "Access denied",
|
|
4893
5041
|
data: {
|
|
@@ -6100,6 +6248,7 @@ export {
|
|
|
6100
6248
|
prefetchWellKnown,
|
|
6101
6249
|
quickVerify,
|
|
6102
6250
|
recordDecision2 as recordDecision,
|
|
6251
|
+
reportAttempt,
|
|
6103
6252
|
reportUnregisteredAttempt,
|
|
6104
6253
|
sanitizeHeaders,
|
|
6105
6254
|
sdk_exports as sdk,
|