@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.
- 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 +85 -8
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +85 -8
- 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 +90 -8
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +90 -8
- 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 +86 -8
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +86 -8
- 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 +71 -8
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +71 -8
- 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 +71 -8
- package/dist/bin/astrasync-codex-hook.js +71 -8
- package/dist/bin/astrasync-guard.js +71 -8
- package/dist/bin/astrasync.js +71 -8
- package/dist/browser/background.js +71 -8
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +71 -8
- 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 +71 -8
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +71 -8
- 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 +71 -8
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +71 -8
- 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-B39o89gf.d.mts → express-BZajRs4i.d.mts} +1 -1
- package/dist/{express-BuxKNO_q.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 +71 -8
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +71 -8
- 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-DME3w3lf.d.mts → index-B0cyMZDL.d.mts} +1 -1
- package/dist/{index-CqydB4ks.d.mts → index-BRYteOqO.d.mts} +1 -1
- package/dist/{index-BG62SXso.d.ts → index-BZQdVqNw.d.ts} +1 -1
- package/dist/{index-CLHdqs2M.d.ts → index-adgKhujR.d.ts} +1 -1
- package/dist/index.d.mts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +119 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +119 -8
- 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-Ddlw_J1J.d.ts → nextjs-D_iFf5k-.d.ts} +1 -1
- package/dist/{nextjs-D74W7wt-.d.mts → nextjs-DeUTnOBd.d.mts} +1 -1
- package/dist/{sdk-CT7gdkfR.d.ts → sdk-BM3mwEAq.d.ts} +1 -1
- package/dist/{sdk-Bn6bj7kt.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-BntuzEEn.d.mts → types-BcDf9Kk0.d.mts} +15 -0
- package/dist/{types-DHu7m9HI.d.ts → types-CHKCgDFC.d.ts} +1 -1
- package/dist/{types-Djw4GLtz.d.mts → types-DfnP7JiM.d.mts} +1 -1
- package/dist/{types-SDu4Llbe.d.ts → types-fTQD448H.d.ts} +15 -0
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +4 -2
- package/dist/verify.d.ts +4 -2
- package/dist/verify.js +76 -8
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +75 -8
- 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,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:
|
|
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(
|
|
538
|
+
await performInitCheck(
|
|
539
|
+
mergedConfig.apiBaseUrl,
|
|
540
|
+
mergedConfig.debug,
|
|
541
|
+
true,
|
|
542
|
+
mergedConfig.apiKey
|
|
543
|
+
);
|
|
487
544
|
} else {
|
|
488
|
-
void performInitCheck(
|
|
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: {
|