@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
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import 'next/server';
|
|
2
|
-
import '../types-
|
|
3
|
-
export { c as createMatcherConfig, a as createMiddleware } from '../nextjs-
|
|
2
|
+
import '../types-BcDf9Kk0.mjs';
|
|
3
|
+
export { c as createMatcherConfig, a as createMiddleware } from '../nextjs-DeUTnOBd.mjs';
|
|
4
4
|
import '../metadata-capture.mjs';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import 'next/server';
|
|
2
|
-
import '../types-
|
|
3
|
-
export { c as createMatcherConfig, a as createMiddleware } from '../nextjs-
|
|
2
|
+
import '../types-fTQD448H.js';
|
|
3
|
+
export { c as createMatcherConfig, a as createMiddleware } from '../nextjs-D_iFf5k-.js';
|
|
4
4
|
import '../metadata-capture.js';
|
package/dist/adapters/nextjs.js
CHANGED
|
@@ -102,7 +102,7 @@ function getTrustLevel(score) {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
// src/version.ts
|
|
105
|
-
var SDK_VERSION = "
|
|
105
|
+
var SDK_VERSION = "4.0.0";
|
|
106
106
|
|
|
107
107
|
// src/well-known.ts
|
|
108
108
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -128,7 +128,7 @@ var DEFAULT_CONFIG = {
|
|
|
128
128
|
};
|
|
129
129
|
var initCheckPerformed = false;
|
|
130
130
|
var deprecationWarningShown = false;
|
|
131
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
131
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
132
132
|
initCheckPerformed = true;
|
|
133
133
|
try {
|
|
134
134
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -145,6 +145,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
|
145
145
|
`[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
|
|
146
146
|
);
|
|
147
147
|
}
|
|
148
|
+
if (apiKey) {
|
|
149
|
+
const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
|
|
150
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
151
|
+
});
|
|
152
|
+
if (selfCheck.status === 401) {
|
|
153
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
154
|
+
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}` : "") + `.`;
|
|
155
|
+
if (strictInit) {
|
|
156
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
157
|
+
}
|
|
158
|
+
console.error(message);
|
|
159
|
+
} else if (selfCheck.ok) {
|
|
160
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
161
|
+
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
162
|
+
console.warn(
|
|
163
|
+
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
164
|
+
);
|
|
165
|
+
} else if (debug) {
|
|
166
|
+
console.log("[VerificationGateway] API key self-check passed");
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
148
170
|
} catch (err) {
|
|
149
171
|
if (strictInit) {
|
|
150
172
|
throw err;
|
|
@@ -222,8 +244,17 @@ function cacheResult(request, result, configuredTtl, counterpartyId) {
|
|
|
222
244
|
function createGuidanceResponse(_config, reason, options = {}) {
|
|
223
245
|
const source = options.source ?? "no_credentials";
|
|
224
246
|
const isApiError = source === "api_error";
|
|
247
|
+
const isMisconfig = source === "merchant_misconfig";
|
|
225
248
|
const urls = options.urls;
|
|
226
|
-
const guidance =
|
|
249
|
+
const guidance = isMisconfig ? {
|
|
250
|
+
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.",
|
|
251
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
252
|
+
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
253
|
+
steps: [
|
|
254
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
|
|
255
|
+
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
256
|
+
]
|
|
257
|
+
} : isApiError ? {
|
|
227
258
|
message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
|
|
228
259
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
229
260
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
@@ -261,14 +292,24 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
261
292
|
// partners (and their custom onDenied handlers) can branch on
|
|
262
293
|
// dimension. Without this, the synthesised stub was indistinguishable
|
|
263
294
|
// from a real policy deny.
|
|
264
|
-
failures:
|
|
295
|
+
failures: isMisconfig ? [
|
|
296
|
+
{
|
|
297
|
+
dimension: "verify_access.merchant_misconfigured",
|
|
298
|
+
message: reason ?? "The integration API key was rejected by AstraSync",
|
|
299
|
+
guidance: guidance.message
|
|
300
|
+
}
|
|
301
|
+
] : isApiError ? [
|
|
265
302
|
{
|
|
266
303
|
dimension: "verify_access.api_error",
|
|
267
304
|
message: reason ?? "Verification temporarily unavailable",
|
|
268
305
|
guidance: guidance.message
|
|
269
306
|
}
|
|
270
307
|
] : void 0,
|
|
308
|
+
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
309
|
+
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
310
|
+
...isMisconfig && { misconfigured: true },
|
|
271
311
|
correlationId: options.correlationId,
|
|
312
|
+
attemptId: options.attemptId,
|
|
272
313
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
273
314
|
};
|
|
274
315
|
}
|
|
@@ -298,6 +339,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
298
339
|
body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
|
|
299
340
|
if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
|
|
300
341
|
if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
|
|
342
|
+
if (requestData.attemptId) body.attemptId = requestData.attemptId;
|
|
343
|
+
if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
|
|
301
344
|
body.sdkVersion = SDK_VERSION;
|
|
302
345
|
if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
|
|
303
346
|
const meta = {
|
|
@@ -319,12 +362,16 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
319
362
|
const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
320
363
|
method: "POST",
|
|
321
364
|
headers,
|
|
322
|
-
body: JSON.stringify(body)
|
|
365
|
+
body: JSON.stringify(body),
|
|
366
|
+
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
323
367
|
});
|
|
324
368
|
const data = await response.json();
|
|
325
369
|
if (response.status === 410) {
|
|
326
370
|
return {
|
|
327
371
|
success: true,
|
|
372
|
+
// 3.12.0 (Trust Record): keep the server-echoed attempt handle even on
|
|
373
|
+
// the synthesised 410 deny shape (echoed on every branch).
|
|
374
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
328
375
|
access: {
|
|
329
376
|
allowed: false,
|
|
330
377
|
accessLevel: "none",
|
|
@@ -340,10 +387,22 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
340
387
|
};
|
|
341
388
|
}
|
|
342
389
|
if (!response.ok) {
|
|
390
|
+
if (response.status === 401) {
|
|
391
|
+
return {
|
|
392
|
+
success: false,
|
|
393
|
+
error: data.message || data.error || "Integration API key rejected",
|
|
394
|
+
misconfig: true,
|
|
395
|
+
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
396
|
+
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
397
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
398
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
399
|
+
};
|
|
400
|
+
}
|
|
343
401
|
return {
|
|
344
402
|
success: false,
|
|
345
403
|
error: data.message || data.error || `API returned ${response.status}`,
|
|
346
|
-
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0
|
|
404
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
405
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
347
406
|
};
|
|
348
407
|
}
|
|
349
408
|
return data;
|
|
@@ -360,9 +419,19 @@ async function verify(config, request, options) {
|
|
|
360
419
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
361
420
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
362
421
|
if (mergedConfig.strictInit) {
|
|
363
|
-
await performInitCheck(
|
|
422
|
+
await performInitCheck(
|
|
423
|
+
mergedConfig.apiBaseUrl,
|
|
424
|
+
mergedConfig.debug,
|
|
425
|
+
true,
|
|
426
|
+
mergedConfig.apiKey
|
|
427
|
+
);
|
|
364
428
|
} else {
|
|
365
|
-
void performInitCheck(
|
|
429
|
+
void performInitCheck(
|
|
430
|
+
mergedConfig.apiBaseUrl,
|
|
431
|
+
mergedConfig.debug,
|
|
432
|
+
false,
|
|
433
|
+
mergedConfig.apiKey
|
|
434
|
+
);
|
|
366
435
|
}
|
|
367
436
|
}
|
|
368
437
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
@@ -377,7 +446,13 @@ async function verify(config, request, options) {
|
|
|
377
446
|
if (mergedConfig.debug) {
|
|
378
447
|
console.log("[VerificationGateway] Returning cached result");
|
|
379
448
|
}
|
|
380
|
-
|
|
449
|
+
const hit = { ...cached };
|
|
450
|
+
if (request.attemptId) {
|
|
451
|
+
hit.attemptId = request.attemptId;
|
|
452
|
+
} else {
|
|
453
|
+
delete hit.attemptId;
|
|
454
|
+
}
|
|
455
|
+
return hit;
|
|
381
456
|
}
|
|
382
457
|
}
|
|
383
458
|
const enrichedRequest = { ...request };
|
|
@@ -395,8 +470,10 @@ async function verify(config, request, options) {
|
|
|
395
470
|
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
396
471
|
if (!apiResponse.success) {
|
|
397
472
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
398
|
-
source: "api_error",
|
|
473
|
+
source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
|
|
399
474
|
correlationId: apiResponse.correlationId,
|
|
475
|
+
attemptId: apiResponse.attemptId,
|
|
476
|
+
remediation: apiResponse.remediation,
|
|
400
477
|
urls
|
|
401
478
|
});
|
|
402
479
|
}
|
|
@@ -432,6 +509,9 @@ async function verify(config, request, options) {
|
|
|
432
509
|
// Anonymous traffic has no session → correlationId is the per-attempt
|
|
433
510
|
// linking key (the sessionId-equivalent for anonymous callers).
|
|
434
511
|
correlationId: apiResponse.correlationId,
|
|
512
|
+
// 3.12.0 (Trust Record): server echoes the attempt-chain handle on
|
|
513
|
+
// every branch — denials included (the funnel outlives one deny).
|
|
514
|
+
attemptId: apiResponse.attemptId,
|
|
435
515
|
recommendation: apiResponse.recommendation,
|
|
436
516
|
recommendationReasons: apiResponse.recommendationReasons,
|
|
437
517
|
stepUpApproval: apiResponse.stepUpApproval,
|
|
@@ -483,6 +563,8 @@ async function verify(config, request, options) {
|
|
|
483
563
|
// v2.3.10 (defect #34, round-4): anonymous responses surface correlationId
|
|
484
564
|
// (no session row exists for unverified callers).
|
|
485
565
|
correlationId: apiResponse.correlationId,
|
|
566
|
+
// 3.12.0 (Trust Record): server-echoed attempt-chain handle.
|
|
567
|
+
attemptId: apiResponse.attemptId,
|
|
486
568
|
runtimeChallenge: apiResponse.runtimeChallenge,
|
|
487
569
|
tokenGuidance: apiResponse.tokenGuidance,
|
|
488
570
|
recommendation: apiResponse.recommendation,
|
|
@@ -1250,6 +1332,21 @@ function createMiddleware(options) {
|
|
|
1250
1332
|
const approvalRequired = result.identityVerified && result.policyAllowed && requiresHumanApproval(result);
|
|
1251
1333
|
if (approvalRequired) annotateApprovalRequired(result);
|
|
1252
1334
|
if (!result.identityVerified || !result.policyAllowed || approvalRequired) {
|
|
1335
|
+
if (result.misconfigured && pathname.startsWith("/api/")) {
|
|
1336
|
+
return NextResponse.json(
|
|
1337
|
+
{
|
|
1338
|
+
success: false,
|
|
1339
|
+
error: {
|
|
1340
|
+
code: "MERCHANT_VERIFICATION_MISCONFIGURED",
|
|
1341
|
+
message: result.denialReasons?.[0] || "This site's AstraSync integration is misconfigured",
|
|
1342
|
+
guidance: result.guidance,
|
|
1343
|
+
failures: result.failures,
|
|
1344
|
+
correlationId: result.correlationId
|
|
1345
|
+
}
|
|
1346
|
+
},
|
|
1347
|
+
{ status: 503 }
|
|
1348
|
+
);
|
|
1349
|
+
}
|
|
1253
1350
|
if (pathname.startsWith("/api/")) {
|
|
1254
1351
|
return NextResponse.json(
|
|
1255
1352
|
{
|