@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/adapters/nextjs.mjs
CHANGED
|
@@ -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;
|
|
@@ -91,7 +91,7 @@ var DEFAULT_CONFIG = {
|
|
|
91
91
|
};
|
|
92
92
|
var initCheckPerformed = false;
|
|
93
93
|
var deprecationWarningShown = false;
|
|
94
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
94
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
95
95
|
initCheckPerformed = true;
|
|
96
96
|
try {
|
|
97
97
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -108,6 +108,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
|
108
108
|
`[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
|
|
109
109
|
);
|
|
110
110
|
}
|
|
111
|
+
if (apiKey) {
|
|
112
|
+
const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
|
|
113
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
114
|
+
});
|
|
115
|
+
if (selfCheck.status === 401) {
|
|
116
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
117
|
+
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}` : "") + `.`;
|
|
118
|
+
if (strictInit) {
|
|
119
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
120
|
+
}
|
|
121
|
+
console.error(message);
|
|
122
|
+
} else if (selfCheck.ok) {
|
|
123
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
124
|
+
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
125
|
+
console.warn(
|
|
126
|
+
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
127
|
+
);
|
|
128
|
+
} else if (debug) {
|
|
129
|
+
console.log("[VerificationGateway] API key self-check passed");
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
111
133
|
} catch (err) {
|
|
112
134
|
if (strictInit) {
|
|
113
135
|
throw err;
|
|
@@ -185,8 +207,17 @@ function cacheResult(request, result, configuredTtl, counterpartyId) {
|
|
|
185
207
|
function createGuidanceResponse(_config, reason, options = {}) {
|
|
186
208
|
const source = options.source ?? "no_credentials";
|
|
187
209
|
const isApiError = source === "api_error";
|
|
210
|
+
const isMisconfig = source === "merchant_misconfig";
|
|
188
211
|
const urls = options.urls;
|
|
189
|
-
const guidance =
|
|
212
|
+
const guidance = isMisconfig ? {
|
|
213
|
+
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.",
|
|
214
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
215
|
+
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
216
|
+
steps: [
|
|
217
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
|
|
218
|
+
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
219
|
+
]
|
|
220
|
+
} : isApiError ? {
|
|
190
221
|
message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
|
|
191
222
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
192
223
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
@@ -224,14 +255,24 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
224
255
|
// partners (and their custom onDenied handlers) can branch on
|
|
225
256
|
// dimension. Without this, the synthesised stub was indistinguishable
|
|
226
257
|
// from a real policy deny.
|
|
227
|
-
failures:
|
|
258
|
+
failures: isMisconfig ? [
|
|
259
|
+
{
|
|
260
|
+
dimension: "verify_access.merchant_misconfigured",
|
|
261
|
+
message: reason ?? "The integration API key was rejected by AstraSync",
|
|
262
|
+
guidance: guidance.message
|
|
263
|
+
}
|
|
264
|
+
] : isApiError ? [
|
|
228
265
|
{
|
|
229
266
|
dimension: "verify_access.api_error",
|
|
230
267
|
message: reason ?? "Verification temporarily unavailable",
|
|
231
268
|
guidance: guidance.message
|
|
232
269
|
}
|
|
233
270
|
] : void 0,
|
|
271
|
+
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
272
|
+
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
273
|
+
...isMisconfig && { misconfigured: true },
|
|
234
274
|
correlationId: options.correlationId,
|
|
275
|
+
attemptId: options.attemptId,
|
|
235
276
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
236
277
|
};
|
|
237
278
|
}
|
|
@@ -261,6 +302,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
261
302
|
body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
|
|
262
303
|
if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
|
|
263
304
|
if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
|
|
305
|
+
if (requestData.attemptId) body.attemptId = requestData.attemptId;
|
|
306
|
+
if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
|
|
264
307
|
body.sdkVersion = SDK_VERSION;
|
|
265
308
|
if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
|
|
266
309
|
const meta = {
|
|
@@ -282,12 +325,16 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
282
325
|
const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
283
326
|
method: "POST",
|
|
284
327
|
headers,
|
|
285
|
-
body: JSON.stringify(body)
|
|
328
|
+
body: JSON.stringify(body),
|
|
329
|
+
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
286
330
|
});
|
|
287
331
|
const data = await response.json();
|
|
288
332
|
if (response.status === 410) {
|
|
289
333
|
return {
|
|
290
334
|
success: true,
|
|
335
|
+
// 3.12.0 (Trust Record): keep the server-echoed attempt handle even on
|
|
336
|
+
// the synthesised 410 deny shape (echoed on every branch).
|
|
337
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
291
338
|
access: {
|
|
292
339
|
allowed: false,
|
|
293
340
|
accessLevel: "none",
|
|
@@ -303,10 +350,22 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
303
350
|
};
|
|
304
351
|
}
|
|
305
352
|
if (!response.ok) {
|
|
353
|
+
if (response.status === 401) {
|
|
354
|
+
return {
|
|
355
|
+
success: false,
|
|
356
|
+
error: data.message || data.error || "Integration API key rejected",
|
|
357
|
+
misconfig: true,
|
|
358
|
+
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
359
|
+
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
360
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
361
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
362
|
+
};
|
|
363
|
+
}
|
|
306
364
|
return {
|
|
307
365
|
success: false,
|
|
308
366
|
error: data.message || data.error || `API returned ${response.status}`,
|
|
309
|
-
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0
|
|
367
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
368
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
310
369
|
};
|
|
311
370
|
}
|
|
312
371
|
return data;
|
|
@@ -323,9 +382,19 @@ async function verify(config, request, options) {
|
|
|
323
382
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
324
383
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
325
384
|
if (mergedConfig.strictInit) {
|
|
326
|
-
await performInitCheck(
|
|
385
|
+
await performInitCheck(
|
|
386
|
+
mergedConfig.apiBaseUrl,
|
|
387
|
+
mergedConfig.debug,
|
|
388
|
+
true,
|
|
389
|
+
mergedConfig.apiKey
|
|
390
|
+
);
|
|
327
391
|
} else {
|
|
328
|
-
void performInitCheck(
|
|
392
|
+
void performInitCheck(
|
|
393
|
+
mergedConfig.apiBaseUrl,
|
|
394
|
+
mergedConfig.debug,
|
|
395
|
+
false,
|
|
396
|
+
mergedConfig.apiKey
|
|
397
|
+
);
|
|
329
398
|
}
|
|
330
399
|
}
|
|
331
400
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
@@ -340,7 +409,13 @@ async function verify(config, request, options) {
|
|
|
340
409
|
if (mergedConfig.debug) {
|
|
341
410
|
console.log("[VerificationGateway] Returning cached result");
|
|
342
411
|
}
|
|
343
|
-
|
|
412
|
+
const hit = { ...cached };
|
|
413
|
+
if (request.attemptId) {
|
|
414
|
+
hit.attemptId = request.attemptId;
|
|
415
|
+
} else {
|
|
416
|
+
delete hit.attemptId;
|
|
417
|
+
}
|
|
418
|
+
return hit;
|
|
344
419
|
}
|
|
345
420
|
}
|
|
346
421
|
const enrichedRequest = { ...request };
|
|
@@ -358,8 +433,10 @@ async function verify(config, request, options) {
|
|
|
358
433
|
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
359
434
|
if (!apiResponse.success) {
|
|
360
435
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
361
|
-
source: "api_error",
|
|
436
|
+
source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
|
|
362
437
|
correlationId: apiResponse.correlationId,
|
|
438
|
+
attemptId: apiResponse.attemptId,
|
|
439
|
+
remediation: apiResponse.remediation,
|
|
363
440
|
urls
|
|
364
441
|
});
|
|
365
442
|
}
|
|
@@ -395,6 +472,9 @@ async function verify(config, request, options) {
|
|
|
395
472
|
// Anonymous traffic has no session → correlationId is the per-attempt
|
|
396
473
|
// linking key (the sessionId-equivalent for anonymous callers).
|
|
397
474
|
correlationId: apiResponse.correlationId,
|
|
475
|
+
// 3.12.0 (Trust Record): server echoes the attempt-chain handle on
|
|
476
|
+
// every branch — denials included (the funnel outlives one deny).
|
|
477
|
+
attemptId: apiResponse.attemptId,
|
|
398
478
|
recommendation: apiResponse.recommendation,
|
|
399
479
|
recommendationReasons: apiResponse.recommendationReasons,
|
|
400
480
|
stepUpApproval: apiResponse.stepUpApproval,
|
|
@@ -446,6 +526,8 @@ async function verify(config, request, options) {
|
|
|
446
526
|
// v2.3.10 (defect #34, round-4): anonymous responses surface correlationId
|
|
447
527
|
// (no session row exists for unverified callers).
|
|
448
528
|
correlationId: apiResponse.correlationId,
|
|
529
|
+
// 3.12.0 (Trust Record): server-echoed attempt-chain handle.
|
|
530
|
+
attemptId: apiResponse.attemptId,
|
|
449
531
|
runtimeChallenge: apiResponse.runtimeChallenge,
|
|
450
532
|
tokenGuidance: apiResponse.tokenGuidance,
|
|
451
533
|
recommendation: apiResponse.recommendation,
|
|
@@ -1213,6 +1295,21 @@ function createMiddleware(options) {
|
|
|
1213
1295
|
const approvalRequired = result.identityVerified && result.policyAllowed && requiresHumanApproval(result);
|
|
1214
1296
|
if (approvalRequired) annotateApprovalRequired(result);
|
|
1215
1297
|
if (!result.identityVerified || !result.policyAllowed || approvalRequired) {
|
|
1298
|
+
if (result.misconfigured && pathname.startsWith("/api/")) {
|
|
1299
|
+
return NextResponse.json(
|
|
1300
|
+
{
|
|
1301
|
+
success: false,
|
|
1302
|
+
error: {
|
|
1303
|
+
code: "MERCHANT_VERIFICATION_MISCONFIGURED",
|
|
1304
|
+
message: result.denialReasons?.[0] || "This site's AstraSync integration is misconfigured",
|
|
1305
|
+
guidance: result.guidance,
|
|
1306
|
+
failures: result.failures,
|
|
1307
|
+
correlationId: result.correlationId
|
|
1308
|
+
}
|
|
1309
|
+
},
|
|
1310
|
+
{ status: 503 }
|
|
1311
|
+
);
|
|
1312
|
+
}
|
|
1216
1313
|
if (pathname.startsWith("/api/")) {
|
|
1217
1314
|
return NextResponse.json(
|
|
1218
1315
|
{
|