@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
|
@@ -65,7 +65,7 @@ function getTrustLevel(score) {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
// src/version.ts
|
|
68
|
-
var SDK_VERSION = "
|
|
68
|
+
var SDK_VERSION = "4.0.0";
|
|
69
69
|
|
|
70
70
|
// src/well-known.ts
|
|
71
71
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -143,7 +143,7 @@ var DEFAULT_CONFIG = {
|
|
|
143
143
|
};
|
|
144
144
|
var initCheckPerformed = false;
|
|
145
145
|
var deprecationWarningShown = false;
|
|
146
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
146
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
147
147
|
initCheckPerformed = true;
|
|
148
148
|
try {
|
|
149
149
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -160,6 +160,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
|
160
160
|
`[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
|
|
161
161
|
);
|
|
162
162
|
}
|
|
163
|
+
if (apiKey) {
|
|
164
|
+
const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
|
|
165
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
166
|
+
});
|
|
167
|
+
if (selfCheck.status === 401) {
|
|
168
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
169
|
+
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}` : "") + `.`;
|
|
170
|
+
if (strictInit) {
|
|
171
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
172
|
+
}
|
|
173
|
+
console.error(message);
|
|
174
|
+
} else if (selfCheck.ok) {
|
|
175
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
176
|
+
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
177
|
+
console.warn(
|
|
178
|
+
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
179
|
+
);
|
|
180
|
+
} else if (debug) {
|
|
181
|
+
console.log("[VerificationGateway] API key self-check passed");
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
163
185
|
} catch (err) {
|
|
164
186
|
if (strictInit) {
|
|
165
187
|
throw err;
|
|
@@ -271,8 +293,17 @@ function extractCredentials(headers, query) {
|
|
|
271
293
|
function createGuidanceResponse(_config, reason, options = {}) {
|
|
272
294
|
const source = options.source ?? "no_credentials";
|
|
273
295
|
const isApiError = source === "api_error";
|
|
296
|
+
const isMisconfig = source === "merchant_misconfig";
|
|
274
297
|
const urls = options.urls;
|
|
275
|
-
const guidance =
|
|
298
|
+
const guidance = isMisconfig ? {
|
|
299
|
+
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.",
|
|
300
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
301
|
+
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
302
|
+
steps: [
|
|
303
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
|
|
304
|
+
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
305
|
+
]
|
|
306
|
+
} : isApiError ? {
|
|
276
307
|
message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
|
|
277
308
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
278
309
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
@@ -310,14 +341,24 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
310
341
|
// partners (and their custom onDenied handlers) can branch on
|
|
311
342
|
// dimension. Without this, the synthesised stub was indistinguishable
|
|
312
343
|
// from a real policy deny.
|
|
313
|
-
failures:
|
|
344
|
+
failures: isMisconfig ? [
|
|
345
|
+
{
|
|
346
|
+
dimension: "verify_access.merchant_misconfigured",
|
|
347
|
+
message: reason ?? "The integration API key was rejected by AstraSync",
|
|
348
|
+
guidance: guidance.message
|
|
349
|
+
}
|
|
350
|
+
] : isApiError ? [
|
|
314
351
|
{
|
|
315
352
|
dimension: "verify_access.api_error",
|
|
316
353
|
message: reason ?? "Verification temporarily unavailable",
|
|
317
354
|
guidance: guidance.message
|
|
318
355
|
}
|
|
319
356
|
] : void 0,
|
|
357
|
+
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
358
|
+
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
359
|
+
...isMisconfig && { misconfigured: true },
|
|
320
360
|
correlationId: options.correlationId,
|
|
361
|
+
attemptId: options.attemptId,
|
|
321
362
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
322
363
|
};
|
|
323
364
|
}
|
|
@@ -347,6 +388,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
347
388
|
body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
|
|
348
389
|
if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
|
|
349
390
|
if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
|
|
391
|
+
if (requestData.attemptId) body.attemptId = requestData.attemptId;
|
|
392
|
+
if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
|
|
350
393
|
body.sdkVersion = SDK_VERSION;
|
|
351
394
|
if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
|
|
352
395
|
const meta = {
|
|
@@ -368,12 +411,16 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
368
411
|
const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
369
412
|
method: "POST",
|
|
370
413
|
headers,
|
|
371
|
-
body: JSON.stringify(body)
|
|
414
|
+
body: JSON.stringify(body),
|
|
415
|
+
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
372
416
|
});
|
|
373
417
|
const data = await response.json();
|
|
374
418
|
if (response.status === 410) {
|
|
375
419
|
return {
|
|
376
420
|
success: true,
|
|
421
|
+
// 3.12.0 (Trust Record): keep the server-echoed attempt handle even on
|
|
422
|
+
// the synthesised 410 deny shape (echoed on every branch).
|
|
423
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
377
424
|
access: {
|
|
378
425
|
allowed: false,
|
|
379
426
|
accessLevel: "none",
|
|
@@ -389,10 +436,22 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
389
436
|
};
|
|
390
437
|
}
|
|
391
438
|
if (!response.ok) {
|
|
439
|
+
if (response.status === 401) {
|
|
440
|
+
return {
|
|
441
|
+
success: false,
|
|
442
|
+
error: data.message || data.error || "Integration API key rejected",
|
|
443
|
+
misconfig: true,
|
|
444
|
+
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
445
|
+
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
446
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
447
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
448
|
+
};
|
|
449
|
+
}
|
|
392
450
|
return {
|
|
393
451
|
success: false,
|
|
394
452
|
error: data.message || data.error || `API returned ${response.status}`,
|
|
395
|
-
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0
|
|
453
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
454
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
396
455
|
};
|
|
397
456
|
}
|
|
398
457
|
return data;
|
|
@@ -409,9 +468,19 @@ async function verify(config, request, options) {
|
|
|
409
468
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
410
469
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
411
470
|
if (mergedConfig.strictInit) {
|
|
412
|
-
await performInitCheck(
|
|
471
|
+
await performInitCheck(
|
|
472
|
+
mergedConfig.apiBaseUrl,
|
|
473
|
+
mergedConfig.debug,
|
|
474
|
+
true,
|
|
475
|
+
mergedConfig.apiKey
|
|
476
|
+
);
|
|
413
477
|
} else {
|
|
414
|
-
void performInitCheck(
|
|
478
|
+
void performInitCheck(
|
|
479
|
+
mergedConfig.apiBaseUrl,
|
|
480
|
+
mergedConfig.debug,
|
|
481
|
+
false,
|
|
482
|
+
mergedConfig.apiKey
|
|
483
|
+
);
|
|
415
484
|
}
|
|
416
485
|
}
|
|
417
486
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
@@ -426,7 +495,13 @@ async function verify(config, request, options) {
|
|
|
426
495
|
if (mergedConfig.debug) {
|
|
427
496
|
console.log("[VerificationGateway] Returning cached result");
|
|
428
497
|
}
|
|
429
|
-
|
|
498
|
+
const hit = { ...cached };
|
|
499
|
+
if (request.attemptId) {
|
|
500
|
+
hit.attemptId = request.attemptId;
|
|
501
|
+
} else {
|
|
502
|
+
delete hit.attemptId;
|
|
503
|
+
}
|
|
504
|
+
return hit;
|
|
430
505
|
}
|
|
431
506
|
}
|
|
432
507
|
const enrichedRequest = { ...request };
|
|
@@ -444,8 +519,10 @@ async function verify(config, request, options) {
|
|
|
444
519
|
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
445
520
|
if (!apiResponse.success) {
|
|
446
521
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
447
|
-
source: "api_error",
|
|
522
|
+
source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
|
|
448
523
|
correlationId: apiResponse.correlationId,
|
|
524
|
+
attemptId: apiResponse.attemptId,
|
|
525
|
+
remediation: apiResponse.remediation,
|
|
449
526
|
urls
|
|
450
527
|
});
|
|
451
528
|
}
|
|
@@ -481,6 +558,9 @@ async function verify(config, request, options) {
|
|
|
481
558
|
// Anonymous traffic has no session → correlationId is the per-attempt
|
|
482
559
|
// linking key (the sessionId-equivalent for anonymous callers).
|
|
483
560
|
correlationId: apiResponse.correlationId,
|
|
561
|
+
// 3.12.0 (Trust Record): server echoes the attempt-chain handle on
|
|
562
|
+
// every branch — denials included (the funnel outlives one deny).
|
|
563
|
+
attemptId: apiResponse.attemptId,
|
|
484
564
|
recommendation: apiResponse.recommendation,
|
|
485
565
|
recommendationReasons: apiResponse.recommendationReasons,
|
|
486
566
|
stepUpApproval: apiResponse.stepUpApproval,
|
|
@@ -532,6 +612,8 @@ async function verify(config, request, options) {
|
|
|
532
612
|
// v2.3.10 (defect #34, round-4): anonymous responses surface correlationId
|
|
533
613
|
// (no session row exists for unverified callers).
|
|
534
614
|
correlationId: apiResponse.correlationId,
|
|
615
|
+
// 3.12.0 (Trust Record): server-echoed attempt-chain handle.
|
|
616
|
+
attemptId: apiResponse.attemptId,
|
|
535
617
|
runtimeChallenge: apiResponse.runtimeChallenge,
|
|
536
618
|
tokenGuidance: apiResponse.tokenGuidance,
|
|
537
619
|
recommendation: apiResponse.recommendation,
|
|
@@ -997,6 +1079,20 @@ function dedupeFailures(result) {
|
|
|
997
1079
|
}
|
|
998
1080
|
}
|
|
999
1081
|
function defaultOnDenied(result, _req, res) {
|
|
1082
|
+
if (result.misconfigured) {
|
|
1083
|
+
res.setHeader("X-Astra-Gateway-Mode", "enforced");
|
|
1084
|
+
res.status(503).json({
|
|
1085
|
+
success: false,
|
|
1086
|
+
error: {
|
|
1087
|
+
code: "MERCHANT_VERIFICATION_MISCONFIGURED",
|
|
1088
|
+
message: result.denialReasons?.[0] || "This site's AstraSync integration is misconfigured",
|
|
1089
|
+
guidance: result.guidance,
|
|
1090
|
+
failures: result.failures,
|
|
1091
|
+
correlationId: result.correlationId
|
|
1092
|
+
}
|
|
1093
|
+
});
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1000
1096
|
const statusCode = !result.identityVerified ? 401 : 403;
|
|
1001
1097
|
res.setHeader("X-Astra-Gateway-Mode", "enforced");
|
|
1002
1098
|
res.status(statusCode).json({
|