@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/verify.mjs
CHANGED
|
@@ -7,7 +7,7 @@ function getTrustLevel(score) {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
// src/version.ts
|
|
10
|
-
var SDK_VERSION = "
|
|
10
|
+
var SDK_VERSION = "4.0.0";
|
|
11
11
|
|
|
12
12
|
// src/well-known.ts
|
|
13
13
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -32,8 +32,11 @@ var DEFAULT_CONFIG = {
|
|
|
32
32
|
debug: false
|
|
33
33
|
};
|
|
34
34
|
var initCheckPerformed = false;
|
|
35
|
+
function _resetInitCheck() {
|
|
36
|
+
initCheckPerformed = false;
|
|
37
|
+
}
|
|
35
38
|
var deprecationWarningShown = false;
|
|
36
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
39
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
37
40
|
initCheckPerformed = true;
|
|
38
41
|
try {
|
|
39
42
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -50,6 +53,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
|
50
53
|
`[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
|
|
51
54
|
);
|
|
52
55
|
}
|
|
56
|
+
if (apiKey) {
|
|
57
|
+
const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
|
|
58
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
59
|
+
});
|
|
60
|
+
if (selfCheck.status === 401) {
|
|
61
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
62
|
+
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}` : "") + `.`;
|
|
63
|
+
if (strictInit) {
|
|
64
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
65
|
+
}
|
|
66
|
+
console.error(message);
|
|
67
|
+
} else if (selfCheck.ok) {
|
|
68
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
69
|
+
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
70
|
+
console.warn(
|
|
71
|
+
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
72
|
+
);
|
|
73
|
+
} else if (debug) {
|
|
74
|
+
console.log("[VerificationGateway] API key self-check passed");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
53
78
|
} catch (err) {
|
|
54
79
|
if (strictInit) {
|
|
55
80
|
throw err;
|
|
@@ -167,8 +192,17 @@ function hasCredentials(credentials) {
|
|
|
167
192
|
function createGuidanceResponse(_config, reason, options = {}) {
|
|
168
193
|
const source = options.source ?? "no_credentials";
|
|
169
194
|
const isApiError = source === "api_error";
|
|
195
|
+
const isMisconfig = source === "merchant_misconfig";
|
|
170
196
|
const urls = options.urls;
|
|
171
|
-
const guidance =
|
|
197
|
+
const guidance = isMisconfig ? {
|
|
198
|
+
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.",
|
|
199
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
200
|
+
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
201
|
+
steps: [
|
|
202
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
|
|
203
|
+
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
204
|
+
]
|
|
205
|
+
} : isApiError ? {
|
|
172
206
|
message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
|
|
173
207
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
174
208
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
@@ -206,14 +240,24 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
206
240
|
// partners (and their custom onDenied handlers) can branch on
|
|
207
241
|
// dimension. Without this, the synthesised stub was indistinguishable
|
|
208
242
|
// from a real policy deny.
|
|
209
|
-
failures:
|
|
243
|
+
failures: isMisconfig ? [
|
|
244
|
+
{
|
|
245
|
+
dimension: "verify_access.merchant_misconfigured",
|
|
246
|
+
message: reason ?? "The integration API key was rejected by AstraSync",
|
|
247
|
+
guidance: guidance.message
|
|
248
|
+
}
|
|
249
|
+
] : isApiError ? [
|
|
210
250
|
{
|
|
211
251
|
dimension: "verify_access.api_error",
|
|
212
252
|
message: reason ?? "Verification temporarily unavailable",
|
|
213
253
|
guidance: guidance.message
|
|
214
254
|
}
|
|
215
255
|
] : void 0,
|
|
256
|
+
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
257
|
+
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
258
|
+
...isMisconfig && { misconfigured: true },
|
|
216
259
|
correlationId: options.correlationId,
|
|
260
|
+
attemptId: options.attemptId,
|
|
217
261
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
218
262
|
};
|
|
219
263
|
}
|
|
@@ -243,6 +287,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
243
287
|
body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
|
|
244
288
|
if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
|
|
245
289
|
if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
|
|
290
|
+
if (requestData.attemptId) body.attemptId = requestData.attemptId;
|
|
291
|
+
if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
|
|
246
292
|
body.sdkVersion = SDK_VERSION;
|
|
247
293
|
if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
|
|
248
294
|
const meta = {
|
|
@@ -264,12 +310,16 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
264
310
|
const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
265
311
|
method: "POST",
|
|
266
312
|
headers,
|
|
267
|
-
body: JSON.stringify(body)
|
|
313
|
+
body: JSON.stringify(body),
|
|
314
|
+
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
268
315
|
});
|
|
269
316
|
const data = await response.json();
|
|
270
317
|
if (response.status === 410) {
|
|
271
318
|
return {
|
|
272
319
|
success: true,
|
|
320
|
+
// 3.12.0 (Trust Record): keep the server-echoed attempt handle even on
|
|
321
|
+
// the synthesised 410 deny shape (echoed on every branch).
|
|
322
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
273
323
|
access: {
|
|
274
324
|
allowed: false,
|
|
275
325
|
accessLevel: "none",
|
|
@@ -285,10 +335,22 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
285
335
|
};
|
|
286
336
|
}
|
|
287
337
|
if (!response.ok) {
|
|
338
|
+
if (response.status === 401) {
|
|
339
|
+
return {
|
|
340
|
+
success: false,
|
|
341
|
+
error: data.message || data.error || "Integration API key rejected",
|
|
342
|
+
misconfig: true,
|
|
343
|
+
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
344
|
+
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
345
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
346
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
347
|
+
};
|
|
348
|
+
}
|
|
288
349
|
return {
|
|
289
350
|
success: false,
|
|
290
351
|
error: data.message || data.error || `API returned ${response.status}`,
|
|
291
|
-
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0
|
|
352
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
353
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
292
354
|
};
|
|
293
355
|
}
|
|
294
356
|
return data;
|
|
@@ -305,9 +367,19 @@ async function verify(config, request, options) {
|
|
|
305
367
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
306
368
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
307
369
|
if (mergedConfig.strictInit) {
|
|
308
|
-
await performInitCheck(
|
|
370
|
+
await performInitCheck(
|
|
371
|
+
mergedConfig.apiBaseUrl,
|
|
372
|
+
mergedConfig.debug,
|
|
373
|
+
true,
|
|
374
|
+
mergedConfig.apiKey
|
|
375
|
+
);
|
|
309
376
|
} else {
|
|
310
|
-
void performInitCheck(
|
|
377
|
+
void performInitCheck(
|
|
378
|
+
mergedConfig.apiBaseUrl,
|
|
379
|
+
mergedConfig.debug,
|
|
380
|
+
false,
|
|
381
|
+
mergedConfig.apiKey
|
|
382
|
+
);
|
|
311
383
|
}
|
|
312
384
|
}
|
|
313
385
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
@@ -322,7 +394,13 @@ async function verify(config, request, options) {
|
|
|
322
394
|
if (mergedConfig.debug) {
|
|
323
395
|
console.log("[VerificationGateway] Returning cached result");
|
|
324
396
|
}
|
|
325
|
-
|
|
397
|
+
const hit = { ...cached };
|
|
398
|
+
if (request.attemptId) {
|
|
399
|
+
hit.attemptId = request.attemptId;
|
|
400
|
+
} else {
|
|
401
|
+
delete hit.attemptId;
|
|
402
|
+
}
|
|
403
|
+
return hit;
|
|
326
404
|
}
|
|
327
405
|
}
|
|
328
406
|
const enrichedRequest = { ...request };
|
|
@@ -340,8 +418,10 @@ async function verify(config, request, options) {
|
|
|
340
418
|
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
341
419
|
if (!apiResponse.success) {
|
|
342
420
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
343
|
-
source: "api_error",
|
|
421
|
+
source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
|
|
344
422
|
correlationId: apiResponse.correlationId,
|
|
423
|
+
attemptId: apiResponse.attemptId,
|
|
424
|
+
remediation: apiResponse.remediation,
|
|
345
425
|
urls
|
|
346
426
|
});
|
|
347
427
|
}
|
|
@@ -377,6 +457,9 @@ async function verify(config, request, options) {
|
|
|
377
457
|
// Anonymous traffic has no session → correlationId is the per-attempt
|
|
378
458
|
// linking key (the sessionId-equivalent for anonymous callers).
|
|
379
459
|
correlationId: apiResponse.correlationId,
|
|
460
|
+
// 3.12.0 (Trust Record): server echoes the attempt-chain handle on
|
|
461
|
+
// every branch — denials included (the funnel outlives one deny).
|
|
462
|
+
attemptId: apiResponse.attemptId,
|
|
380
463
|
recommendation: apiResponse.recommendation,
|
|
381
464
|
recommendationReasons: apiResponse.recommendationReasons,
|
|
382
465
|
stepUpApproval: apiResponse.stepUpApproval,
|
|
@@ -428,6 +511,8 @@ async function verify(config, request, options) {
|
|
|
428
511
|
// v2.3.10 (defect #34, round-4): anonymous responses surface correlationId
|
|
429
512
|
// (no session row exists for unverified callers).
|
|
430
513
|
correlationId: apiResponse.correlationId,
|
|
514
|
+
// 3.12.0 (Trust Record): server-echoed attempt-chain handle.
|
|
515
|
+
attemptId: apiResponse.attemptId,
|
|
431
516
|
runtimeChallenge: apiResponse.runtimeChallenge,
|
|
432
517
|
tokenGuidance: apiResponse.tokenGuidance,
|
|
433
518
|
recommendation: apiResponse.recommendation,
|
|
@@ -472,6 +557,24 @@ async function recordDecision(config, sessionId, decision, reason) {
|
|
|
472
557
|
}).catch(() => {
|
|
473
558
|
});
|
|
474
559
|
}
|
|
560
|
+
async function reportAttempt(config, report) {
|
|
561
|
+
const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
|
|
562
|
+
const headers = { "Content-Type": "application/json" };
|
|
563
|
+
if (config.apiKey) {
|
|
564
|
+
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
565
|
+
headers["X-API-Key"] = config.apiKey;
|
|
566
|
+
}
|
|
567
|
+
const body = {
|
|
568
|
+
...report,
|
|
569
|
+
...!report.counterpartyId && config.counterpartyId && { counterpartyId: config.counterpartyId }
|
|
570
|
+
};
|
|
571
|
+
await fetch(`${apiBaseUrl}/agents/verify-access/attempt-report`, {
|
|
572
|
+
method: "POST",
|
|
573
|
+
headers,
|
|
574
|
+
body: JSON.stringify(body)
|
|
575
|
+
}).catch(() => {
|
|
576
|
+
});
|
|
577
|
+
}
|
|
475
578
|
async function fetchRoutes(config, counterpartyId) {
|
|
476
579
|
if (!counterpartyId) return null;
|
|
477
580
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -543,12 +646,14 @@ async function quickVerify(config, credentials) {
|
|
|
543
646
|
};
|
|
544
647
|
}
|
|
545
648
|
export {
|
|
649
|
+
_resetInitCheck,
|
|
546
650
|
clearCache,
|
|
547
651
|
extractCredentials,
|
|
548
652
|
fetchRoutes,
|
|
549
653
|
hasCredentials,
|
|
550
654
|
quickVerify,
|
|
551
655
|
recordDecision,
|
|
656
|
+
reportAttempt,
|
|
552
657
|
reportCounterpartyPreCheckFailure,
|
|
553
658
|
reportUnregisteredAttempt,
|
|
554
659
|
verify,
|