@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.mjs
CHANGED
|
@@ -126,7 +126,7 @@ function getCapabilities(accessLevel) {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
// src/version.ts
|
|
129
|
-
var SDK_VERSION = "3.
|
|
129
|
+
var SDK_VERSION = "3.6.0";
|
|
130
130
|
|
|
131
131
|
// src/well-known.ts
|
|
132
132
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -196,10 +196,10 @@ var DEFAULT_CONFIG = {
|
|
|
196
196
|
// through (`hasMinimumAccess('guidance', 'guidance') === true`).
|
|
197
197
|
defaultAccessLevel: "none",
|
|
198
198
|
// minTrustScore + minTrustScoreForFull deprecated in v2.3.0 — server decides.
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
// Set cacheTtl: 0 to disable caching entirely.
|
|
199
|
+
// cacheTtl deliberately unset. When undefined, cacheResult applies the 60s
|
|
200
|
+
// default; the caller's explicit value is honoured for cacheable results.
|
|
201
|
+
// Denials and step-up escalations are NEVER cached (3.6.0) regardless of
|
|
202
|
+
// cacheTtl. Set cacheTtl: 0 to disable caching entirely.
|
|
203
203
|
debug: false
|
|
204
204
|
};
|
|
205
205
|
var initCheckPerformed = false;
|
|
@@ -286,10 +286,9 @@ function getCachedResult(request, counterpartyId) {
|
|
|
286
286
|
}
|
|
287
287
|
return null;
|
|
288
288
|
}
|
|
289
|
-
var
|
|
290
|
-
var DEFAULT_STEP_UP_TTL_SECONDS = 300;
|
|
289
|
+
var DEFAULT_CACHE_TTL_SECONDS = 60;
|
|
291
290
|
function cacheResult(request, result, configuredTtl, counterpartyId) {
|
|
292
|
-
const ttlSeconds = configuredTtl && configuredTtl > 0 ? configuredTtl :
|
|
291
|
+
const ttlSeconds = configuredTtl && configuredTtl > 0 ? configuredTtl : DEFAULT_CACHE_TTL_SECONDS;
|
|
293
292
|
const key = getCacheKey(request, counterpartyId);
|
|
294
293
|
verificationCache.set(key, {
|
|
295
294
|
result,
|
|
@@ -471,7 +470,7 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
471
470
|
};
|
|
472
471
|
}
|
|
473
472
|
}
|
|
474
|
-
async function verify(config, request) {
|
|
473
|
+
async function verify(config, request, options) {
|
|
475
474
|
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
|
|
476
475
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
477
476
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
@@ -487,7 +486,7 @@ async function verify(config, request) {
|
|
|
487
486
|
"[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."
|
|
488
487
|
);
|
|
489
488
|
}
|
|
490
|
-
if (mergedConfig.cacheTtl !== 0) {
|
|
489
|
+
if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache) {
|
|
491
490
|
const cached = getCachedResult(request, mergedConfig.counterpartyId);
|
|
492
491
|
if (cached) {
|
|
493
492
|
if (mergedConfig.debug) {
|
|
@@ -507,6 +506,8 @@ async function verify(config, request) {
|
|
|
507
506
|
console.log("[VerificationGateway] Calling verify-access API");
|
|
508
507
|
}
|
|
509
508
|
const apiResponse = await callVerifyAccessAPI(mergedConfig, enrichedRequest);
|
|
509
|
+
const rawServerDenialReasons = apiResponse.denialReasons;
|
|
510
|
+
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
510
511
|
if (!apiResponse.success) {
|
|
511
512
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
512
513
|
source: "api_error",
|
|
@@ -528,7 +529,10 @@ async function verify(config, request) {
|
|
|
528
529
|
// ALSO short-circuit on `!identityVerified || !policyAllowed` before
|
|
529
530
|
// the gate check — belt-and-braces.
|
|
530
531
|
accessLevel: "none",
|
|
531
|
-
|
|
532
|
+
// 3.6.0: the server now emits top-level denialReasons on every deny
|
|
533
|
+
// path — prefer it verbatim; the failure-message reconstruction remains
|
|
534
|
+
// as the fallback for older backends.
|
|
535
|
+
denialReasons: serverDenialReasons ?? (aggregatedFailures && aggregatedFailures.length > 0 ? aggregatedFailures.map((f) => f.message) : apiResponse.access?.reason ? [apiResponse.access.reason] : ["Access denied"]),
|
|
532
536
|
failures: aggregatedFailures,
|
|
533
537
|
requiresStepUp: apiResponse.access?.requiresStepUp,
|
|
534
538
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
@@ -605,9 +609,7 @@ async function verify(config, request) {
|
|
|
605
609
|
if (result.recommendation === "deny") {
|
|
606
610
|
result.policyAllowed = false;
|
|
607
611
|
result.accessLevel = "none";
|
|
608
|
-
result.denialReasons = result.recommendationReasons
|
|
609
|
-
"Access denied by AstraSync recommendation"
|
|
610
|
-
];
|
|
612
|
+
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Access denied by AstraSync recommendation"];
|
|
611
613
|
result.guidance = result.runtimeChallenge ? {
|
|
612
614
|
message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
|
|
613
615
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
@@ -619,9 +621,10 @@ async function verify(config, request) {
|
|
|
619
621
|
};
|
|
620
622
|
} else if (result.recommendation === "step_up_required") {
|
|
621
623
|
result.requiresStepUp = true;
|
|
622
|
-
result.denialReasons = result.recommendationReasons
|
|
624
|
+
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
|
|
623
625
|
}
|
|
624
|
-
|
|
626
|
+
const escalates = result.requiresStepUp === true || result.requiresApproval === true || result.recommendation === "step_up_required";
|
|
627
|
+
if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny" && !escalates) {
|
|
625
628
|
cacheResult(request, result, mergedConfig.cacheTtl, mergedConfig.counterpartyId);
|
|
626
629
|
}
|
|
627
630
|
return result;
|
|
@@ -680,6 +683,64 @@ async function quickVerify(config, credentials) {
|
|
|
680
683
|
};
|
|
681
684
|
}
|
|
682
685
|
|
|
686
|
+
// src/adapters/stepup-poll.ts
|
|
687
|
+
var DEFAULT_POLL_INTERVAL_MS = 3e3;
|
|
688
|
+
var MIN_POLL_INTERVAL_MS = 250;
|
|
689
|
+
var FALLBACK_MAX_WAIT_MS = 5 * 60 * 1e3;
|
|
690
|
+
var EXPIRY_GRACE_MS = 5e3;
|
|
691
|
+
var POLL_REQUEST_TIMEOUT_MS = 1e4;
|
|
692
|
+
function resolvePollUrl(config, pollUrl) {
|
|
693
|
+
if (pollUrl.startsWith("http")) return pollUrl;
|
|
694
|
+
const origin = (config.apiBaseUrl ?? "").replace(/\/api\/?$/, "");
|
|
695
|
+
return origin + pollUrl;
|
|
696
|
+
}
|
|
697
|
+
async function pollStepUpStatus(config, approval) {
|
|
698
|
+
if (!approval.pollUrl) return null;
|
|
699
|
+
try {
|
|
700
|
+
const res = await fetch(resolvePollUrl(config, approval.pollUrl), {
|
|
701
|
+
method: "GET",
|
|
702
|
+
signal: AbortSignal.timeout(POLL_REQUEST_TIMEOUT_MS)
|
|
703
|
+
});
|
|
704
|
+
if (!res.ok) return null;
|
|
705
|
+
const body = await res.json();
|
|
706
|
+
const data = body?.data;
|
|
707
|
+
const status = data && typeof data === "object" ? data.status : body?.status;
|
|
708
|
+
return typeof status === "string" ? status : null;
|
|
709
|
+
} catch {
|
|
710
|
+
return null;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
function resolveDeadline(config, approval) {
|
|
714
|
+
const now = Date.now();
|
|
715
|
+
const maxWait = config.stepUpMaxWaitMs ?? 0;
|
|
716
|
+
if (maxWait > 0) return now + maxWait;
|
|
717
|
+
if (approval.expiresAt) {
|
|
718
|
+
const expiry = Date.parse(approval.expiresAt);
|
|
719
|
+
if (!Number.isNaN(expiry)) return Math.max(now, expiry) + EXPIRY_GRACE_MS;
|
|
720
|
+
}
|
|
721
|
+
return now + FALLBACK_MAX_WAIT_MS;
|
|
722
|
+
}
|
|
723
|
+
function sleep(ms) {
|
|
724
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
725
|
+
}
|
|
726
|
+
async function awaitStepUpApproval(config, approval) {
|
|
727
|
+
const deadline = resolveDeadline(config, approval);
|
|
728
|
+
const pollInterval = Math.max(
|
|
729
|
+
MIN_POLL_INTERVAL_MS,
|
|
730
|
+
config.stepUpPollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS
|
|
731
|
+
);
|
|
732
|
+
while (Date.now() < deadline) {
|
|
733
|
+
const status = await pollStepUpStatus(config, approval);
|
|
734
|
+
if (status && status !== "pending") {
|
|
735
|
+
return status;
|
|
736
|
+
}
|
|
737
|
+
const remaining = deadline - Date.now();
|
|
738
|
+
if (remaining <= 0) break;
|
|
739
|
+
await sleep(Math.min(pollInterval, remaining));
|
|
740
|
+
}
|
|
741
|
+
return "timeout";
|
|
742
|
+
}
|
|
743
|
+
|
|
683
744
|
// src/adapters/approval-gate.ts
|
|
684
745
|
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.";
|
|
685
746
|
function requiresHumanApproval(result) {
|
|
@@ -1026,7 +1087,10 @@ function defaultOnDenied(result, _req, res) {
|
|
|
1026
1087
|
// Round-10: aggregated per-dimension detail + correlation handle.
|
|
1027
1088
|
failures: result.failures,
|
|
1028
1089
|
correlationId: result.correlationId,
|
|
1029
|
-
stepUpApproval: result.stepUpApproval
|
|
1090
|
+
stepUpApproval: result.stepUpApproval,
|
|
1091
|
+
// 3.6.0: terminal outcome of an opt-in hold-and-poll wait (denied /
|
|
1092
|
+
// expired / consumed / timeout). Absent when the feature is off.
|
|
1093
|
+
...result.stepUpOutcome && { stepUpOutcome: result.stepUpOutcome }
|
|
1030
1094
|
}
|
|
1031
1095
|
});
|
|
1032
1096
|
}
|
|
@@ -1176,7 +1240,22 @@ function createMiddleware(options) {
|
|
|
1176
1240
|
);
|
|
1177
1241
|
}
|
|
1178
1242
|
const agentCardUrl = typeof req.headers["x-astrasync-agent-card"] === "string" ? req.headers["x-astrasync-agent-card"] : void 0;
|
|
1179
|
-
|
|
1243
|
+
let txValue;
|
|
1244
|
+
let txCurrency;
|
|
1245
|
+
if (config.extractTransactionValue) {
|
|
1246
|
+
try {
|
|
1247
|
+
const extracted = config.extractTransactionValue(req);
|
|
1248
|
+
if (extracted) {
|
|
1249
|
+
txValue = extracted.value;
|
|
1250
|
+
txCurrency = extracted.currency;
|
|
1251
|
+
}
|
|
1252
|
+
} catch (e) {
|
|
1253
|
+
if (config.debug) {
|
|
1254
|
+
console.warn("[VerificationGateway] extractTransactionValue threw:", e);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
const verificationRequest = {
|
|
1180
1259
|
credentials,
|
|
1181
1260
|
purpose,
|
|
1182
1261
|
action: pdlssPair.action,
|
|
@@ -1186,6 +1265,8 @@ function createMiddleware(options) {
|
|
|
1186
1265
|
counterpartyType: config.counterpartyType || "api",
|
|
1187
1266
|
enableRuntimeChallenge,
|
|
1188
1267
|
durationRequired: astraCreds?.pdlss?.duration?.maxSessionDuration,
|
|
1268
|
+
...txValue !== void 0 && { transactionValue: txValue },
|
|
1269
|
+
...txCurrency && { currency: txCurrency },
|
|
1189
1270
|
callerMetadata: {
|
|
1190
1271
|
sourceIp: originalClientIp,
|
|
1191
1272
|
userAgent: req.headers["user-agent"],
|
|
@@ -1194,9 +1275,21 @@ function createMiddleware(options) {
|
|
|
1194
1275
|
forwardedFor: forwardedForStr,
|
|
1195
1276
|
agentCardUrl
|
|
1196
1277
|
}
|
|
1197
|
-
}
|
|
1278
|
+
};
|
|
1279
|
+
let result = await verify(config, verificationRequest);
|
|
1198
1280
|
req.agentVerification = result;
|
|
1199
|
-
|
|
1281
|
+
let sessionId = result.sessionId;
|
|
1282
|
+
if (config.stepUpMaxWaitMs !== void 0 && result.identityVerified && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
|
|
1283
|
+
const outcome = await awaitStepUpApproval(config, result.stepUpApproval);
|
|
1284
|
+
res.setHeader("X-Astra-Step-Up", outcome);
|
|
1285
|
+
if (outcome === "approved") {
|
|
1286
|
+
result = await verify(config, verificationRequest, { bypassCache: true });
|
|
1287
|
+
req.agentVerification = result;
|
|
1288
|
+
sessionId = result.sessionId;
|
|
1289
|
+
} else {
|
|
1290
|
+
result.stepUpOutcome = outcome;
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1200
1293
|
if (!result.identityVerified || !result.policyAllowed) {
|
|
1201
1294
|
if (shouldRecordDecisions && sessionId) {
|
|
1202
1295
|
recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
|
|
@@ -1645,7 +1738,7 @@ function createMiddleware2(options) {
|
|
|
1645
1738
|
}
|
|
1646
1739
|
const forwardedFor = request.headers.get("x-forwarded-for") || void 0;
|
|
1647
1740
|
const originalClientIp = forwardedFor?.split(",")[0]?.trim();
|
|
1648
|
-
const
|
|
1741
|
+
const verificationRequest = {
|
|
1649
1742
|
credentials,
|
|
1650
1743
|
purpose,
|
|
1651
1744
|
action: pdlssPair.action,
|
|
@@ -1662,7 +1755,17 @@ function createMiddleware2(options) {
|
|
|
1662
1755
|
forwardedFor,
|
|
1663
1756
|
agentCardUrl: request.headers.get("x-astrasync-agent-card") || void 0
|
|
1664
1757
|
}
|
|
1665
|
-
}
|
|
1758
|
+
};
|
|
1759
|
+
let result = await verify(config, verificationRequest);
|
|
1760
|
+
let stepUpHoldOutcome;
|
|
1761
|
+
if (config.stepUpMaxWaitMs !== void 0 && result.identityVerified && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
|
|
1762
|
+
stepUpHoldOutcome = await awaitStepUpApproval(config, result.stepUpApproval);
|
|
1763
|
+
if (stepUpHoldOutcome === "approved") {
|
|
1764
|
+
result = await verify(config, verificationRequest, { bypassCache: true });
|
|
1765
|
+
} else {
|
|
1766
|
+
result.stepUpOutcome = stepUpHoldOutcome;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1666
1769
|
const approvalRequired = result.identityVerified && result.policyAllowed && requiresHumanApproval(result);
|
|
1667
1770
|
if (approvalRequired) annotateApprovalRequired(result);
|
|
1668
1771
|
if (!result.identityVerified || !result.policyAllowed || approvalRequired) {
|
|
@@ -1677,10 +1780,17 @@ function createMiddleware2(options) {
|
|
|
1677
1780
|
message: result.denialReasons?.[0] || "Access denied",
|
|
1678
1781
|
guidance: result.guidance,
|
|
1679
1782
|
failures: result.failures,
|
|
1680
|
-
stepUpApproval: result.stepUpApproval
|
|
1783
|
+
stepUpApproval: result.stepUpApproval,
|
|
1784
|
+
// 3.6.0: terminal outcome of an opt-in hold-and-poll wait.
|
|
1785
|
+
...result.stepUpOutcome && { stepUpOutcome: result.stepUpOutcome }
|
|
1681
1786
|
}
|
|
1682
1787
|
},
|
|
1683
|
-
{
|
|
1788
|
+
{
|
|
1789
|
+
status: !result.identityVerified ? 401 : 403,
|
|
1790
|
+
...stepUpHoldOutcome && {
|
|
1791
|
+
headers: { "X-Astra-Step-Up": stepUpHoldOutcome }
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1684
1794
|
);
|
|
1685
1795
|
}
|
|
1686
1796
|
if (showCommerceShield) {
|
|
@@ -1699,6 +1809,9 @@ function createMiddleware2(options) {
|
|
|
1699
1809
|
"X-AstraSync-Verified",
|
|
1700
1810
|
(result.identityVerified && result.policyAllowed).toString()
|
|
1701
1811
|
);
|
|
1812
|
+
if (stepUpHoldOutcome) {
|
|
1813
|
+
response.headers.set("X-Astra-Step-Up", stepUpHoldOutcome);
|
|
1814
|
+
}
|
|
1702
1815
|
response.headers.set("X-AstraSync-Identity-Verified", result.identityVerified.toString());
|
|
1703
1816
|
response.headers.set("X-AstraSync-Policy-Allowed", result.policyAllowed.toString());
|
|
1704
1817
|
response.headers.set("X-AstraSync-Access-Level", result.accessLevel);
|
|
@@ -2166,15 +2279,33 @@ function extractMPPTransactionValue(challenge) {
|
|
|
2166
2279
|
source: `challenge.request.amount (method=${challenge.method ?? "unknown"})`
|
|
2167
2280
|
};
|
|
2168
2281
|
}
|
|
2282
|
+
var KNOWN_TOKEN_DECIMALS = {
|
|
2283
|
+
USDC: 6,
|
|
2284
|
+
USDT: 6,
|
|
2285
|
+
DAI: 18,
|
|
2286
|
+
ETH: 18,
|
|
2287
|
+
WETH: 18
|
|
2288
|
+
};
|
|
2169
2289
|
function extractX402TransactionValue(req) {
|
|
2170
|
-
const
|
|
2290
|
+
const rawAmount = req.maxAmountRequired ?? req.amount;
|
|
2171
2291
|
const currency = req.currency ?? req.asset;
|
|
2172
|
-
if (typeof
|
|
2292
|
+
if (typeof rawAmount !== "number" || !currency) return null;
|
|
2293
|
+
const source = req.maxAmountRequired !== void 0 ? "maxAmountRequired" : "amount";
|
|
2294
|
+
const decimals = KNOWN_TOKEN_DECIMALS[currency.toUpperCase()];
|
|
2295
|
+
if (decimals !== void 0) {
|
|
2296
|
+
return {
|
|
2297
|
+
protocol: "x402",
|
|
2298
|
+
amount: rawAmount / Math.pow(10, decimals),
|
|
2299
|
+
currency,
|
|
2300
|
+
source
|
|
2301
|
+
};
|
|
2302
|
+
}
|
|
2173
2303
|
return {
|
|
2174
2304
|
protocol: "x402",
|
|
2175
|
-
amount,
|
|
2305
|
+
amount: rawAmount,
|
|
2176
2306
|
currency,
|
|
2177
|
-
source
|
|
2307
|
+
source,
|
|
2308
|
+
rawUnits: true
|
|
2178
2309
|
};
|
|
2179
2310
|
}
|
|
2180
2311
|
|
|
@@ -4581,7 +4712,10 @@ function defaultMcpDenied(result, req, res) {
|
|
|
4581
4712
|
// Round-10: aggregated per-dimension detail + correlation handle.
|
|
4582
4713
|
failures: result.failures,
|
|
4583
4714
|
correlationId: result.correlationId,
|
|
4584
|
-
stepUpApproval: result.stepUpApproval
|
|
4715
|
+
stepUpApproval: result.stepUpApproval,
|
|
4716
|
+
// 3.6.0: terminal outcome of an opt-in hold-and-poll wait (denied /
|
|
4717
|
+
// expired / consumed / timeout). Absent when the feature is off.
|
|
4718
|
+
...result.stepUpOutcome && { stepUpOutcome: result.stepUpOutcome }
|
|
4585
4719
|
}
|
|
4586
4720
|
}
|
|
4587
4721
|
});
|
|
@@ -4722,7 +4856,7 @@ function createMcpMiddleware(options) {
|
|
|
4722
4856
|
}
|
|
4723
4857
|
const counterpartyUrl = config.counterpartyUrl || `${req.protocol}://${req.get("host")}${req.path}`;
|
|
4724
4858
|
const shouldRecordDecisions = recordDecisions !== false;
|
|
4725
|
-
const
|
|
4859
|
+
const verificationRequest = {
|
|
4726
4860
|
credentials,
|
|
4727
4861
|
purpose: pdlss.purpose,
|
|
4728
4862
|
action: pdlss.action,
|
|
@@ -4740,9 +4874,21 @@ function createMcpMiddleware(options) {
|
|
|
4740
4874
|
userAgent: req.headers["user-agent"],
|
|
4741
4875
|
host: req.headers.host
|
|
4742
4876
|
}
|
|
4743
|
-
}
|
|
4877
|
+
};
|
|
4878
|
+
let result = await verify(config, verificationRequest);
|
|
4744
4879
|
req.agentVerification = result;
|
|
4745
|
-
|
|
4880
|
+
let sessionId = result.sessionId;
|
|
4881
|
+
if (config.stepUpMaxWaitMs !== void 0 && result.identityVerified && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
|
|
4882
|
+
const outcome = await awaitStepUpApproval(config, result.stepUpApproval);
|
|
4883
|
+
res.setHeader("X-Astra-Step-Up", outcome);
|
|
4884
|
+
if (outcome === "approved") {
|
|
4885
|
+
result = await verify(config, verificationRequest, { bypassCache: true });
|
|
4886
|
+
req.agentVerification = result;
|
|
4887
|
+
sessionId = result.sessionId;
|
|
4888
|
+
} else {
|
|
4889
|
+
result.stepUpOutcome = outcome;
|
|
4890
|
+
}
|
|
4891
|
+
}
|
|
4746
4892
|
if (!result.identityVerified || !result.policyAllowed) {
|
|
4747
4893
|
if (shouldRecordDecisions && sessionId) {
|
|
4748
4894
|
recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
|
|
@@ -4896,7 +5042,7 @@ var RegistrationTimeoutError = class extends AstraSyncError {
|
|
|
4896
5042
|
|
|
4897
5043
|
// src/registration/api.ts
|
|
4898
5044
|
var DEFAULT_BASE_URL = "https://astrasync.ai";
|
|
4899
|
-
var
|
|
5045
|
+
var sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
4900
5046
|
var AstraSync = class {
|
|
4901
5047
|
constructor(config = {}) {
|
|
4902
5048
|
let raw = (config.baseUrl || process.env.ASTRASYNC_API_URL || DEFAULT_BASE_URL).replace(
|
|
@@ -5058,7 +5204,7 @@ var AstraSync = class {
|
|
|
5058
5204
|
if (result.state === "expired") {
|
|
5059
5205
|
throw new RegistrationExpiredError(requestId);
|
|
5060
5206
|
}
|
|
5061
|
-
await
|
|
5207
|
+
await sleep2(pollIntervalMs);
|
|
5062
5208
|
}
|
|
5063
5209
|
throw new RegistrationTimeoutError(requestId);
|
|
5064
5210
|
}
|
|
@@ -5527,6 +5673,7 @@ export {
|
|
|
5527
5673
|
VERSION,
|
|
5528
5674
|
agent_exports as agent,
|
|
5529
5675
|
authorizeSettlement,
|
|
5676
|
+
awaitStepUpApproval,
|
|
5530
5677
|
buildGuidance,
|
|
5531
5678
|
clearCache,
|
|
5532
5679
|
createMcpMiddleware,
|
|
@@ -5542,6 +5689,7 @@ export {
|
|
|
5542
5689
|
hasCredentials,
|
|
5543
5690
|
hasMinimumAccess,
|
|
5544
5691
|
nextjs_exports as nextjs,
|
|
5692
|
+
pollStepUpStatus,
|
|
5545
5693
|
prefetchWellKnown,
|
|
5546
5694
|
quickVerify,
|
|
5547
5695
|
recordDecision2 as recordDecision,
|