@astrasyncai/verification-gateway 3.4.0 → 3.6.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/README.md +102 -0
- 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 +113 -20
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +113 -20
- 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 +96 -20
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +96 -20
- 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 +101 -20
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +101 -20
- 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 +19 -16
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +19 -16
- 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/browser/background.js +22 -16
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +22 -16
- 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/cli/index.d.mts +2 -2
- package/dist/cli/index.d.ts +2 -2
- 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 +22 -16
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +22 -16
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/{express-CeFvNWDD.d.mts → express-BnMO-H3y.d.mts} +1 -1
- package/dist/{express-RIh05wW2.d.ts → express-DQhDzNAt.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 +22 -16
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +22 -16
- 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-DgVBEiwI.d.mts → index-BT_aRn-I.d.mts} +1 -1
- package/dist/{index-BYu1FKMy.d.ts → index-D8-dvUFA.d.ts} +1 -1
- package/dist/{index-Bw4FeHMY.d.mts → index-WHKq2v17.d.mts} +5 -1
- package/dist/{index-C-K0WCrk.d.ts → index-rftma0ln.d.ts} +5 -1
- package/dist/index.d.mts +55 -9
- package/dist/index.d.ts +55 -9
- package/dist/index.js +184 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +182 -34
- 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-xciaMpsZ.d.mts → nextjs-DFKYhxe6.d.mts} +1 -1
- package/dist/{nextjs--xR9zbSJ.d.ts → nextjs-DPj7ZNlq.d.ts} +1 -1
- package/dist/{sdk-FP7xT9F8.d.ts → sdk-CAcHgB5x.d.ts} +1 -1
- package/dist/{sdk-CJYCLMI0.d.mts → sdk-Cy3wAmDt.d.mts} +1 -1
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/transport/index.js +22 -4
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +22 -4
- package/dist/transport/index.mjs.map +1 -1
- package/dist/{types-Cj92yKeA.d.mts → types-B-ubjHER.d.mts} +1 -1
- package/dist/{types-DOeL-dIw.d.ts → types-Bgn5gxHQ.d.ts} +1 -1
- package/dist/{types-Cwrvo30g.d.mts → types-CKe8O0lR.d.mts} +65 -3
- package/dist/{types-Cwrvo30g.d.ts → types-CKe8O0lR.d.ts} +65 -3
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -46,6 +46,7 @@ __export(src_exports, {
|
|
|
46
46
|
VERSION: () => VERSION,
|
|
47
47
|
agent: () => agent_exports,
|
|
48
48
|
authorizeSettlement: () => authorizeSettlement,
|
|
49
|
+
awaitStepUpApproval: () => awaitStepUpApproval,
|
|
49
50
|
buildGuidance: () => buildGuidance,
|
|
50
51
|
clearCache: () => clearCache,
|
|
51
52
|
createMcpMiddleware: () => createMcpMiddleware,
|
|
@@ -61,6 +62,7 @@ __export(src_exports, {
|
|
|
61
62
|
hasCredentials: () => hasCredentials,
|
|
62
63
|
hasMinimumAccess: () => hasMinimumAccess,
|
|
63
64
|
nextjs: () => nextjs_exports,
|
|
65
|
+
pollStepUpStatus: () => pollStepUpStatus,
|
|
64
66
|
prefetchWellKnown: () => prefetchWellKnown,
|
|
65
67
|
quickVerify: () => quickVerify,
|
|
66
68
|
recordDecision: () => recordDecision2,
|
|
@@ -193,7 +195,7 @@ function getCapabilities(accessLevel) {
|
|
|
193
195
|
}
|
|
194
196
|
|
|
195
197
|
// src/version.ts
|
|
196
|
-
var SDK_VERSION = "3.
|
|
198
|
+
var SDK_VERSION = "3.6.0";
|
|
197
199
|
|
|
198
200
|
// src/well-known.ts
|
|
199
201
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -263,10 +265,10 @@ var DEFAULT_CONFIG = {
|
|
|
263
265
|
// through (`hasMinimumAccess('guidance', 'guidance') === true`).
|
|
264
266
|
defaultAccessLevel: "none",
|
|
265
267
|
// minTrustScore + minTrustScoreForFull deprecated in v2.3.0 — server decides.
|
|
266
|
-
//
|
|
267
|
-
//
|
|
268
|
-
//
|
|
269
|
-
// Set cacheTtl: 0 to disable caching entirely.
|
|
268
|
+
// cacheTtl deliberately unset. When undefined, cacheResult applies the 60s
|
|
269
|
+
// default; the caller's explicit value is honoured for cacheable results.
|
|
270
|
+
// Denials and step-up escalations are NEVER cached (3.6.0) regardless of
|
|
271
|
+
// cacheTtl. Set cacheTtl: 0 to disable caching entirely.
|
|
270
272
|
debug: false
|
|
271
273
|
};
|
|
272
274
|
var initCheckPerformed = false;
|
|
@@ -353,10 +355,9 @@ function getCachedResult(request, counterpartyId) {
|
|
|
353
355
|
}
|
|
354
356
|
return null;
|
|
355
357
|
}
|
|
356
|
-
var
|
|
357
|
-
var DEFAULT_STEP_UP_TTL_SECONDS = 300;
|
|
358
|
+
var DEFAULT_CACHE_TTL_SECONDS = 60;
|
|
358
359
|
function cacheResult(request, result, configuredTtl, counterpartyId) {
|
|
359
|
-
const ttlSeconds = configuredTtl && configuredTtl > 0 ? configuredTtl :
|
|
360
|
+
const ttlSeconds = configuredTtl && configuredTtl > 0 ? configuredTtl : DEFAULT_CACHE_TTL_SECONDS;
|
|
360
361
|
const key = getCacheKey(request, counterpartyId);
|
|
361
362
|
verificationCache.set(key, {
|
|
362
363
|
result,
|
|
@@ -538,7 +539,7 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
538
539
|
};
|
|
539
540
|
}
|
|
540
541
|
}
|
|
541
|
-
async function verify(config, request) {
|
|
542
|
+
async function verify(config, request, options) {
|
|
542
543
|
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
|
|
543
544
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
544
545
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
@@ -554,7 +555,7 @@ async function verify(config, request) {
|
|
|
554
555
|
"[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access-level decisions (the SDK reads access.accessLevel from the verify-access response). To gate access to an endpoint, configure the endpoint's trust_score_requirement server-side."
|
|
555
556
|
);
|
|
556
557
|
}
|
|
557
|
-
if (mergedConfig.cacheTtl !== 0) {
|
|
558
|
+
if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache) {
|
|
558
559
|
const cached = getCachedResult(request, mergedConfig.counterpartyId);
|
|
559
560
|
if (cached) {
|
|
560
561
|
if (mergedConfig.debug) {
|
|
@@ -574,6 +575,8 @@ async function verify(config, request) {
|
|
|
574
575
|
console.log("[VerificationGateway] Calling verify-access API");
|
|
575
576
|
}
|
|
576
577
|
const apiResponse = await callVerifyAccessAPI(mergedConfig, enrichedRequest);
|
|
578
|
+
const rawServerDenialReasons = apiResponse.denialReasons;
|
|
579
|
+
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
577
580
|
if (!apiResponse.success) {
|
|
578
581
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
579
582
|
source: "api_error",
|
|
@@ -595,7 +598,10 @@ async function verify(config, request) {
|
|
|
595
598
|
// ALSO short-circuit on `!identityVerified || !policyAllowed` before
|
|
596
599
|
// the gate check — belt-and-braces.
|
|
597
600
|
accessLevel: "none",
|
|
598
|
-
|
|
601
|
+
// 3.6.0: the server now emits top-level denialReasons on every deny
|
|
602
|
+
// path — prefer it verbatim; the failure-message reconstruction remains
|
|
603
|
+
// as the fallback for older backends.
|
|
604
|
+
denialReasons: serverDenialReasons ?? (aggregatedFailures && aggregatedFailures.length > 0 ? aggregatedFailures.map((f) => f.message) : apiResponse.access?.reason ? [apiResponse.access.reason] : ["Access denied"]),
|
|
599
605
|
failures: aggregatedFailures,
|
|
600
606
|
requiresStepUp: apiResponse.access?.requiresStepUp,
|
|
601
607
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
@@ -672,9 +678,7 @@ async function verify(config, request) {
|
|
|
672
678
|
if (result.recommendation === "deny") {
|
|
673
679
|
result.policyAllowed = false;
|
|
674
680
|
result.accessLevel = "none";
|
|
675
|
-
result.denialReasons = result.recommendationReasons
|
|
676
|
-
"Access denied by AstraSync recommendation"
|
|
677
|
-
];
|
|
681
|
+
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Access denied by AstraSync recommendation"];
|
|
678
682
|
result.guidance = result.runtimeChallenge ? {
|
|
679
683
|
message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
|
|
680
684
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
@@ -686,9 +690,10 @@ async function verify(config, request) {
|
|
|
686
690
|
};
|
|
687
691
|
} else if (result.recommendation === "step_up_required") {
|
|
688
692
|
result.requiresStepUp = true;
|
|
689
|
-
result.denialReasons = result.recommendationReasons
|
|
693
|
+
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
|
|
690
694
|
}
|
|
691
|
-
|
|
695
|
+
const escalates = result.requiresStepUp === true || result.requiresApproval === true || result.recommendation === "step_up_required";
|
|
696
|
+
if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny" && !escalates) {
|
|
692
697
|
cacheResult(request, result, mergedConfig.cacheTtl, mergedConfig.counterpartyId);
|
|
693
698
|
}
|
|
694
699
|
return result;
|
|
@@ -747,6 +752,64 @@ async function quickVerify(config, credentials) {
|
|
|
747
752
|
};
|
|
748
753
|
}
|
|
749
754
|
|
|
755
|
+
// src/adapters/stepup-poll.ts
|
|
756
|
+
var DEFAULT_POLL_INTERVAL_MS = 3e3;
|
|
757
|
+
var MIN_POLL_INTERVAL_MS = 250;
|
|
758
|
+
var FALLBACK_MAX_WAIT_MS = 5 * 60 * 1e3;
|
|
759
|
+
var EXPIRY_GRACE_MS = 5e3;
|
|
760
|
+
var POLL_REQUEST_TIMEOUT_MS = 1e4;
|
|
761
|
+
function resolvePollUrl(config, pollUrl) {
|
|
762
|
+
if (pollUrl.startsWith("http")) return pollUrl;
|
|
763
|
+
const origin = (config.apiBaseUrl ?? "").replace(/\/api\/?$/, "");
|
|
764
|
+
return origin + pollUrl;
|
|
765
|
+
}
|
|
766
|
+
async function pollStepUpStatus(config, approval) {
|
|
767
|
+
if (!approval.pollUrl) return null;
|
|
768
|
+
try {
|
|
769
|
+
const res = await fetch(resolvePollUrl(config, approval.pollUrl), {
|
|
770
|
+
method: "GET",
|
|
771
|
+
signal: AbortSignal.timeout(POLL_REQUEST_TIMEOUT_MS)
|
|
772
|
+
});
|
|
773
|
+
if (!res.ok) return null;
|
|
774
|
+
const body = await res.json();
|
|
775
|
+
const data = body?.data;
|
|
776
|
+
const status = data && typeof data === "object" ? data.status : body?.status;
|
|
777
|
+
return typeof status === "string" ? status : null;
|
|
778
|
+
} catch {
|
|
779
|
+
return null;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
function resolveDeadline(config, approval) {
|
|
783
|
+
const now = Date.now();
|
|
784
|
+
const maxWait = config.stepUpMaxWaitMs ?? 0;
|
|
785
|
+
if (maxWait > 0) return now + maxWait;
|
|
786
|
+
if (approval.expiresAt) {
|
|
787
|
+
const expiry = Date.parse(approval.expiresAt);
|
|
788
|
+
if (!Number.isNaN(expiry)) return Math.max(now, expiry) + EXPIRY_GRACE_MS;
|
|
789
|
+
}
|
|
790
|
+
return now + FALLBACK_MAX_WAIT_MS;
|
|
791
|
+
}
|
|
792
|
+
function sleep(ms) {
|
|
793
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
794
|
+
}
|
|
795
|
+
async function awaitStepUpApproval(config, approval) {
|
|
796
|
+
const deadline = resolveDeadline(config, approval);
|
|
797
|
+
const pollInterval = Math.max(
|
|
798
|
+
MIN_POLL_INTERVAL_MS,
|
|
799
|
+
config.stepUpPollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS
|
|
800
|
+
);
|
|
801
|
+
while (Date.now() < deadline) {
|
|
802
|
+
const status = await pollStepUpStatus(config, approval);
|
|
803
|
+
if (status && status !== "pending") {
|
|
804
|
+
return status;
|
|
805
|
+
}
|
|
806
|
+
const remaining = deadline - Date.now();
|
|
807
|
+
if (remaining <= 0) break;
|
|
808
|
+
await sleep(Math.min(pollInterval, remaining));
|
|
809
|
+
}
|
|
810
|
+
return "timeout";
|
|
811
|
+
}
|
|
812
|
+
|
|
750
813
|
// src/adapters/approval-gate.ts
|
|
751
814
|
var APPROVAL_REASON = "Transaction is above the autonomous limit and requires human approval. The agent owner can approve or deny this transaction in the AstraSync dashboard.";
|
|
752
815
|
function requiresHumanApproval(result) {
|
|
@@ -1093,7 +1156,10 @@ function defaultOnDenied(result, _req, res) {
|
|
|
1093
1156
|
// Round-10: aggregated per-dimension detail + correlation handle.
|
|
1094
1157
|
failures: result.failures,
|
|
1095
1158
|
correlationId: result.correlationId,
|
|
1096
|
-
stepUpApproval: result.stepUpApproval
|
|
1159
|
+
stepUpApproval: result.stepUpApproval,
|
|
1160
|
+
// 3.6.0: terminal outcome of an opt-in hold-and-poll wait (denied /
|
|
1161
|
+
// expired / consumed / timeout). Absent when the feature is off.
|
|
1162
|
+
...result.stepUpOutcome && { stepUpOutcome: result.stepUpOutcome }
|
|
1097
1163
|
}
|
|
1098
1164
|
});
|
|
1099
1165
|
}
|
|
@@ -1243,7 +1309,22 @@ function createMiddleware(options) {
|
|
|
1243
1309
|
);
|
|
1244
1310
|
}
|
|
1245
1311
|
const agentCardUrl = typeof req.headers["x-astrasync-agent-card"] === "string" ? req.headers["x-astrasync-agent-card"] : void 0;
|
|
1246
|
-
|
|
1312
|
+
let txValue;
|
|
1313
|
+
let txCurrency;
|
|
1314
|
+
if (config.extractTransactionValue) {
|
|
1315
|
+
try {
|
|
1316
|
+
const extracted = config.extractTransactionValue(req);
|
|
1317
|
+
if (extracted) {
|
|
1318
|
+
txValue = extracted.value;
|
|
1319
|
+
txCurrency = extracted.currency;
|
|
1320
|
+
}
|
|
1321
|
+
} catch (e) {
|
|
1322
|
+
if (config.debug) {
|
|
1323
|
+
console.warn("[VerificationGateway] extractTransactionValue threw:", e);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
const verificationRequest = {
|
|
1247
1328
|
credentials,
|
|
1248
1329
|
purpose,
|
|
1249
1330
|
action: pdlssPair.action,
|
|
@@ -1253,6 +1334,8 @@ function createMiddleware(options) {
|
|
|
1253
1334
|
counterpartyType: config.counterpartyType || "api",
|
|
1254
1335
|
enableRuntimeChallenge,
|
|
1255
1336
|
durationRequired: astraCreds?.pdlss?.duration?.maxSessionDuration,
|
|
1337
|
+
...txValue !== void 0 && { transactionValue: txValue },
|
|
1338
|
+
...txCurrency && { currency: txCurrency },
|
|
1256
1339
|
callerMetadata: {
|
|
1257
1340
|
sourceIp: originalClientIp,
|
|
1258
1341
|
userAgent: req.headers["user-agent"],
|
|
@@ -1261,9 +1344,21 @@ function createMiddleware(options) {
|
|
|
1261
1344
|
forwardedFor: forwardedForStr,
|
|
1262
1345
|
agentCardUrl
|
|
1263
1346
|
}
|
|
1264
|
-
}
|
|
1347
|
+
};
|
|
1348
|
+
let result = await verify(config, verificationRequest);
|
|
1265
1349
|
req.agentVerification = result;
|
|
1266
|
-
|
|
1350
|
+
let sessionId = result.sessionId;
|
|
1351
|
+
if (config.stepUpMaxWaitMs !== void 0 && result.identityVerified && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
|
|
1352
|
+
const outcome = await awaitStepUpApproval(config, result.stepUpApproval);
|
|
1353
|
+
res.setHeader("X-Astra-Step-Up", outcome);
|
|
1354
|
+
if (outcome === "approved") {
|
|
1355
|
+
result = await verify(config, verificationRequest, { bypassCache: true });
|
|
1356
|
+
req.agentVerification = result;
|
|
1357
|
+
sessionId = result.sessionId;
|
|
1358
|
+
} else {
|
|
1359
|
+
result.stepUpOutcome = outcome;
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1267
1362
|
if (!result.identityVerified || !result.policyAllowed) {
|
|
1268
1363
|
if (shouldRecordDecisions && sessionId) {
|
|
1269
1364
|
recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
|
|
@@ -1712,7 +1807,7 @@ function createMiddleware2(options) {
|
|
|
1712
1807
|
}
|
|
1713
1808
|
const forwardedFor = request.headers.get("x-forwarded-for") || void 0;
|
|
1714
1809
|
const originalClientIp = forwardedFor?.split(",")[0]?.trim();
|
|
1715
|
-
const
|
|
1810
|
+
const verificationRequest = {
|
|
1716
1811
|
credentials,
|
|
1717
1812
|
purpose,
|
|
1718
1813
|
action: pdlssPair.action,
|
|
@@ -1729,7 +1824,17 @@ function createMiddleware2(options) {
|
|
|
1729
1824
|
forwardedFor,
|
|
1730
1825
|
agentCardUrl: request.headers.get("x-astrasync-agent-card") || void 0
|
|
1731
1826
|
}
|
|
1732
|
-
}
|
|
1827
|
+
};
|
|
1828
|
+
let result = await verify(config, verificationRequest);
|
|
1829
|
+
let stepUpHoldOutcome;
|
|
1830
|
+
if (config.stepUpMaxWaitMs !== void 0 && result.identityVerified && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
|
|
1831
|
+
stepUpHoldOutcome = await awaitStepUpApproval(config, result.stepUpApproval);
|
|
1832
|
+
if (stepUpHoldOutcome === "approved") {
|
|
1833
|
+
result = await verify(config, verificationRequest, { bypassCache: true });
|
|
1834
|
+
} else {
|
|
1835
|
+
result.stepUpOutcome = stepUpHoldOutcome;
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1733
1838
|
const approvalRequired = result.identityVerified && result.policyAllowed && requiresHumanApproval(result);
|
|
1734
1839
|
if (approvalRequired) annotateApprovalRequired(result);
|
|
1735
1840
|
if (!result.identityVerified || !result.policyAllowed || approvalRequired) {
|
|
@@ -1744,10 +1849,17 @@ function createMiddleware2(options) {
|
|
|
1744
1849
|
message: result.denialReasons?.[0] || "Access denied",
|
|
1745
1850
|
guidance: result.guidance,
|
|
1746
1851
|
failures: result.failures,
|
|
1747
|
-
stepUpApproval: result.stepUpApproval
|
|
1852
|
+
stepUpApproval: result.stepUpApproval,
|
|
1853
|
+
// 3.6.0: terminal outcome of an opt-in hold-and-poll wait.
|
|
1854
|
+
...result.stepUpOutcome && { stepUpOutcome: result.stepUpOutcome }
|
|
1748
1855
|
}
|
|
1749
1856
|
},
|
|
1750
|
-
{
|
|
1857
|
+
{
|
|
1858
|
+
status: !result.identityVerified ? 401 : 403,
|
|
1859
|
+
...stepUpHoldOutcome && {
|
|
1860
|
+
headers: { "X-Astra-Step-Up": stepUpHoldOutcome }
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1751
1863
|
);
|
|
1752
1864
|
}
|
|
1753
1865
|
if (showCommerceShield) {
|
|
@@ -1766,6 +1878,9 @@ function createMiddleware2(options) {
|
|
|
1766
1878
|
"X-AstraSync-Verified",
|
|
1767
1879
|
(result.identityVerified && result.policyAllowed).toString()
|
|
1768
1880
|
);
|
|
1881
|
+
if (stepUpHoldOutcome) {
|
|
1882
|
+
response.headers.set("X-Astra-Step-Up", stepUpHoldOutcome);
|
|
1883
|
+
}
|
|
1769
1884
|
response.headers.set("X-AstraSync-Identity-Verified", result.identityVerified.toString());
|
|
1770
1885
|
response.headers.set("X-AstraSync-Policy-Allowed", result.policyAllowed.toString());
|
|
1771
1886
|
response.headers.set("X-AstraSync-Access-Level", result.accessLevel);
|
|
@@ -2233,15 +2348,33 @@ function extractMPPTransactionValue(challenge) {
|
|
|
2233
2348
|
source: `challenge.request.amount (method=${challenge.method ?? "unknown"})`
|
|
2234
2349
|
};
|
|
2235
2350
|
}
|
|
2351
|
+
var KNOWN_TOKEN_DECIMALS = {
|
|
2352
|
+
USDC: 6,
|
|
2353
|
+
USDT: 6,
|
|
2354
|
+
DAI: 18,
|
|
2355
|
+
ETH: 18,
|
|
2356
|
+
WETH: 18
|
|
2357
|
+
};
|
|
2236
2358
|
function extractX402TransactionValue(req) {
|
|
2237
|
-
const
|
|
2359
|
+
const rawAmount = req.maxAmountRequired ?? req.amount;
|
|
2238
2360
|
const currency = req.currency ?? req.asset;
|
|
2239
|
-
if (typeof
|
|
2361
|
+
if (typeof rawAmount !== "number" || !currency) return null;
|
|
2362
|
+
const source = req.maxAmountRequired !== void 0 ? "maxAmountRequired" : "amount";
|
|
2363
|
+
const decimals = KNOWN_TOKEN_DECIMALS[currency.toUpperCase()];
|
|
2364
|
+
if (decimals !== void 0) {
|
|
2365
|
+
return {
|
|
2366
|
+
protocol: "x402",
|
|
2367
|
+
amount: rawAmount / Math.pow(10, decimals),
|
|
2368
|
+
currency,
|
|
2369
|
+
source
|
|
2370
|
+
};
|
|
2371
|
+
}
|
|
2240
2372
|
return {
|
|
2241
2373
|
protocol: "x402",
|
|
2242
|
-
amount,
|
|
2374
|
+
amount: rawAmount,
|
|
2243
2375
|
currency,
|
|
2244
|
-
source
|
|
2376
|
+
source,
|
|
2377
|
+
rawUnits: true
|
|
2245
2378
|
};
|
|
2246
2379
|
}
|
|
2247
2380
|
|
|
@@ -4645,7 +4778,10 @@ function defaultMcpDenied(result, req, res) {
|
|
|
4645
4778
|
// Round-10: aggregated per-dimension detail + correlation handle.
|
|
4646
4779
|
failures: result.failures,
|
|
4647
4780
|
correlationId: result.correlationId,
|
|
4648
|
-
stepUpApproval: result.stepUpApproval
|
|
4781
|
+
stepUpApproval: result.stepUpApproval,
|
|
4782
|
+
// 3.6.0: terminal outcome of an opt-in hold-and-poll wait (denied /
|
|
4783
|
+
// expired / consumed / timeout). Absent when the feature is off.
|
|
4784
|
+
...result.stepUpOutcome && { stepUpOutcome: result.stepUpOutcome }
|
|
4649
4785
|
}
|
|
4650
4786
|
}
|
|
4651
4787
|
});
|
|
@@ -4786,7 +4922,7 @@ function createMcpMiddleware(options) {
|
|
|
4786
4922
|
}
|
|
4787
4923
|
const counterpartyUrl = config.counterpartyUrl || `${req.protocol}://${req.get("host")}${req.path}`;
|
|
4788
4924
|
const shouldRecordDecisions = recordDecisions !== false;
|
|
4789
|
-
const
|
|
4925
|
+
const verificationRequest = {
|
|
4790
4926
|
credentials,
|
|
4791
4927
|
purpose: pdlss.purpose,
|
|
4792
4928
|
action: pdlss.action,
|
|
@@ -4804,9 +4940,21 @@ function createMcpMiddleware(options) {
|
|
|
4804
4940
|
userAgent: req.headers["user-agent"],
|
|
4805
4941
|
host: req.headers.host
|
|
4806
4942
|
}
|
|
4807
|
-
}
|
|
4943
|
+
};
|
|
4944
|
+
let result = await verify(config, verificationRequest);
|
|
4808
4945
|
req.agentVerification = result;
|
|
4809
|
-
|
|
4946
|
+
let sessionId = result.sessionId;
|
|
4947
|
+
if (config.stepUpMaxWaitMs !== void 0 && result.identityVerified && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
|
|
4948
|
+
const outcome = await awaitStepUpApproval(config, result.stepUpApproval);
|
|
4949
|
+
res.setHeader("X-Astra-Step-Up", outcome);
|
|
4950
|
+
if (outcome === "approved") {
|
|
4951
|
+
result = await verify(config, verificationRequest, { bypassCache: true });
|
|
4952
|
+
req.agentVerification = result;
|
|
4953
|
+
sessionId = result.sessionId;
|
|
4954
|
+
} else {
|
|
4955
|
+
result.stepUpOutcome = outcome;
|
|
4956
|
+
}
|
|
4957
|
+
}
|
|
4810
4958
|
if (!result.identityVerified || !result.policyAllowed) {
|
|
4811
4959
|
if (shouldRecordDecisions && sessionId) {
|
|
4812
4960
|
recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
|
|
@@ -4960,7 +5108,7 @@ var RegistrationTimeoutError = class extends AstraSyncError {
|
|
|
4960
5108
|
|
|
4961
5109
|
// src/registration/api.ts
|
|
4962
5110
|
var DEFAULT_BASE_URL = "https://astrasync.ai";
|
|
4963
|
-
var
|
|
5111
|
+
var sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
4964
5112
|
var AstraSync = class {
|
|
4965
5113
|
constructor(config = {}) {
|
|
4966
5114
|
let raw = (config.baseUrl || process.env.ASTRASYNC_API_URL || DEFAULT_BASE_URL).replace(
|
|
@@ -5122,7 +5270,7 @@ var AstraSync = class {
|
|
|
5122
5270
|
if (result.state === "expired") {
|
|
5123
5271
|
throw new RegistrationExpiredError(requestId);
|
|
5124
5272
|
}
|
|
5125
|
-
await
|
|
5273
|
+
await sleep2(pollIntervalMs);
|
|
5126
5274
|
}
|
|
5127
5275
|
throw new RegistrationTimeoutError(requestId);
|
|
5128
5276
|
}
|
|
@@ -5592,6 +5740,7 @@ var VERSION = "3.4.0";
|
|
|
5592
5740
|
VERSION,
|
|
5593
5741
|
agent,
|
|
5594
5742
|
authorizeSettlement,
|
|
5743
|
+
awaitStepUpApproval,
|
|
5595
5744
|
buildGuidance,
|
|
5596
5745
|
clearCache,
|
|
5597
5746
|
createMcpMiddleware,
|
|
@@ -5607,6 +5756,7 @@ var VERSION = "3.4.0";
|
|
|
5607
5756
|
hasCredentials,
|
|
5608
5757
|
hasMinimumAccess,
|
|
5609
5758
|
nextjs,
|
|
5759
|
+
pollStepUpStatus,
|
|
5610
5760
|
prefetchWellKnown,
|
|
5611
5761
|
quickVerify,
|
|
5612
5762
|
recordDecision,
|