@astrasyncai/verification-gateway 3.5.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 +16 -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 +96 -20
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +96 -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-BH5ADAyb.d.mts → express-BnMO-H3y.d.mts} +1 -1
- package/dist/{express-jUzLIoep.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-aZHAWujT.d.mts → index-BT_aRn-I.d.mts} +1 -1
- package/dist/{index-DlCnmpJH.d.ts → index-D8-dvUFA.d.ts} +1 -1
- package/dist/{index-BR2nmxBU.d.mts → index-WHKq2v17.d.mts} +1 -1
- package/dist/{index-DEixUCu0.d.ts → index-rftma0ln.d.ts} +1 -1
- package/dist/index.d.mts +55 -9
- package/dist/index.d.ts +55 -9
- package/dist/index.js +145 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +143 -30
- 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-LTeoPqMH.d.mts → nextjs-DFKYhxe6.d.mts} +1 -1
- package/dist/{nextjs-DfXOd0Au.d.ts → nextjs-DPj7ZNlq.d.ts} +1 -1
- package/dist/{sdk-LmvyDVpL.d.ts → sdk-CAcHgB5x.d.ts} +1 -1
- package/dist/{sdk-DKhwVL9X.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/{types-C8HyQEaz.d.mts → types-B-ubjHER.d.mts} +1 -1
- package/dist/{types-xofemo0G.d.ts → types-Bgn5gxHQ.d.ts} +1 -1
- package/dist/{types-DrDIouvO.d.mts → types-CKe8O0lR.d.mts} +41 -1
- package/dist/{types-DrDIouvO.d.ts → types-CKe8O0lR.d.ts} +41 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import 'next/server';
|
|
2
|
-
import '../types-
|
|
3
|
-
export { c as createMatcherConfig, a as createMiddleware } from '../nextjs-
|
|
2
|
+
import '../types-CKe8O0lR.mjs';
|
|
3
|
+
export { c as createMatcherConfig, a as createMiddleware } from '../nextjs-DFKYhxe6.mjs';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import 'next/server';
|
|
2
|
-
import '../types-
|
|
3
|
-
export { c as createMatcherConfig, a as createMiddleware } from '../nextjs-
|
|
2
|
+
import '../types-CKe8O0lR.js';
|
|
3
|
+
export { c as createMatcherConfig, a as createMiddleware } from '../nextjs-DPj7ZNlq.js';
|
package/dist/adapters/nextjs.js
CHANGED
|
@@ -35,6 +35,64 @@ __export(nextjs_exports, {
|
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(nextjs_exports);
|
|
37
37
|
|
|
38
|
+
// src/adapters/stepup-poll.ts
|
|
39
|
+
var DEFAULT_POLL_INTERVAL_MS = 3e3;
|
|
40
|
+
var MIN_POLL_INTERVAL_MS = 250;
|
|
41
|
+
var FALLBACK_MAX_WAIT_MS = 5 * 60 * 1e3;
|
|
42
|
+
var EXPIRY_GRACE_MS = 5e3;
|
|
43
|
+
var POLL_REQUEST_TIMEOUT_MS = 1e4;
|
|
44
|
+
function resolvePollUrl(config, pollUrl) {
|
|
45
|
+
if (pollUrl.startsWith("http")) return pollUrl;
|
|
46
|
+
const origin = (config.apiBaseUrl ?? "").replace(/\/api\/?$/, "");
|
|
47
|
+
return origin + pollUrl;
|
|
48
|
+
}
|
|
49
|
+
async function pollStepUpStatus(config, approval) {
|
|
50
|
+
if (!approval.pollUrl) return null;
|
|
51
|
+
try {
|
|
52
|
+
const res = await fetch(resolvePollUrl(config, approval.pollUrl), {
|
|
53
|
+
method: "GET",
|
|
54
|
+
signal: AbortSignal.timeout(POLL_REQUEST_TIMEOUT_MS)
|
|
55
|
+
});
|
|
56
|
+
if (!res.ok) return null;
|
|
57
|
+
const body = await res.json();
|
|
58
|
+
const data = body?.data;
|
|
59
|
+
const status = data && typeof data === "object" ? data.status : body?.status;
|
|
60
|
+
return typeof status === "string" ? status : null;
|
|
61
|
+
} catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function resolveDeadline(config, approval) {
|
|
66
|
+
const now = Date.now();
|
|
67
|
+
const maxWait = config.stepUpMaxWaitMs ?? 0;
|
|
68
|
+
if (maxWait > 0) return now + maxWait;
|
|
69
|
+
if (approval.expiresAt) {
|
|
70
|
+
const expiry = Date.parse(approval.expiresAt);
|
|
71
|
+
if (!Number.isNaN(expiry)) return Math.max(now, expiry) + EXPIRY_GRACE_MS;
|
|
72
|
+
}
|
|
73
|
+
return now + FALLBACK_MAX_WAIT_MS;
|
|
74
|
+
}
|
|
75
|
+
function sleep(ms) {
|
|
76
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
77
|
+
}
|
|
78
|
+
async function awaitStepUpApproval(config, approval) {
|
|
79
|
+
const deadline = resolveDeadline(config, approval);
|
|
80
|
+
const pollInterval = Math.max(
|
|
81
|
+
MIN_POLL_INTERVAL_MS,
|
|
82
|
+
config.stepUpPollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS
|
|
83
|
+
);
|
|
84
|
+
while (Date.now() < deadline) {
|
|
85
|
+
const status = await pollStepUpStatus(config, approval);
|
|
86
|
+
if (status && status !== "pending") {
|
|
87
|
+
return status;
|
|
88
|
+
}
|
|
89
|
+
const remaining = deadline - Date.now();
|
|
90
|
+
if (remaining <= 0) break;
|
|
91
|
+
await sleep(Math.min(pollInterval, remaining));
|
|
92
|
+
}
|
|
93
|
+
return "timeout";
|
|
94
|
+
}
|
|
95
|
+
|
|
38
96
|
// src/access-levels.ts
|
|
39
97
|
function getTrustLevel(score) {
|
|
40
98
|
if (score >= 80) return "PLATINUM";
|
|
@@ -44,7 +102,7 @@ function getTrustLevel(score) {
|
|
|
44
102
|
}
|
|
45
103
|
|
|
46
104
|
// src/version.ts
|
|
47
|
-
var SDK_VERSION = "3.
|
|
105
|
+
var SDK_VERSION = "3.6.0";
|
|
48
106
|
|
|
49
107
|
// src/well-known.ts
|
|
50
108
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -62,10 +120,10 @@ var DEFAULT_CONFIG = {
|
|
|
62
120
|
// through (`hasMinimumAccess('guidance', 'guidance') === true`).
|
|
63
121
|
defaultAccessLevel: "none",
|
|
64
122
|
// minTrustScore + minTrustScoreForFull deprecated in v2.3.0 — server decides.
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
// Set cacheTtl: 0 to disable caching entirely.
|
|
123
|
+
// cacheTtl deliberately unset. When undefined, cacheResult applies the 60s
|
|
124
|
+
// default; the caller's explicit value is honoured for cacheable results.
|
|
125
|
+
// Denials and step-up escalations are NEVER cached (3.6.0) regardless of
|
|
126
|
+
// cacheTtl. Set cacheTtl: 0 to disable caching entirely.
|
|
69
127
|
debug: false
|
|
70
128
|
};
|
|
71
129
|
var initCheckPerformed = false;
|
|
@@ -152,10 +210,9 @@ function getCachedResult(request, counterpartyId) {
|
|
|
152
210
|
}
|
|
153
211
|
return null;
|
|
154
212
|
}
|
|
155
|
-
var
|
|
156
|
-
var DEFAULT_STEP_UP_TTL_SECONDS = 300;
|
|
213
|
+
var DEFAULT_CACHE_TTL_SECONDS = 60;
|
|
157
214
|
function cacheResult(request, result, configuredTtl, counterpartyId) {
|
|
158
|
-
const ttlSeconds = configuredTtl && configuredTtl > 0 ? configuredTtl :
|
|
215
|
+
const ttlSeconds = configuredTtl && configuredTtl > 0 ? configuredTtl : DEFAULT_CACHE_TTL_SECONDS;
|
|
159
216
|
const key = getCacheKey(request, counterpartyId);
|
|
160
217
|
verificationCache.set(key, {
|
|
161
218
|
result,
|
|
@@ -297,7 +354,7 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
297
354
|
};
|
|
298
355
|
}
|
|
299
356
|
}
|
|
300
|
-
async function verify(config, request) {
|
|
357
|
+
async function verify(config, request, options) {
|
|
301
358
|
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
|
|
302
359
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
303
360
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
@@ -313,7 +370,7 @@ async function verify(config, request) {
|
|
|
313
370
|
"[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."
|
|
314
371
|
);
|
|
315
372
|
}
|
|
316
|
-
if (mergedConfig.cacheTtl !== 0) {
|
|
373
|
+
if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache) {
|
|
317
374
|
const cached = getCachedResult(request, mergedConfig.counterpartyId);
|
|
318
375
|
if (cached) {
|
|
319
376
|
if (mergedConfig.debug) {
|
|
@@ -333,6 +390,8 @@ async function verify(config, request) {
|
|
|
333
390
|
console.log("[VerificationGateway] Calling verify-access API");
|
|
334
391
|
}
|
|
335
392
|
const apiResponse = await callVerifyAccessAPI(mergedConfig, enrichedRequest);
|
|
393
|
+
const rawServerDenialReasons = apiResponse.denialReasons;
|
|
394
|
+
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
336
395
|
if (!apiResponse.success) {
|
|
337
396
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
338
397
|
source: "api_error",
|
|
@@ -354,7 +413,10 @@ async function verify(config, request) {
|
|
|
354
413
|
// ALSO short-circuit on `!identityVerified || !policyAllowed` before
|
|
355
414
|
// the gate check — belt-and-braces.
|
|
356
415
|
accessLevel: "none",
|
|
357
|
-
|
|
416
|
+
// 3.6.0: the server now emits top-level denialReasons on every deny
|
|
417
|
+
// path — prefer it verbatim; the failure-message reconstruction remains
|
|
418
|
+
// as the fallback for older backends.
|
|
419
|
+
denialReasons: serverDenialReasons ?? (aggregatedFailures && aggregatedFailures.length > 0 ? aggregatedFailures.map((f) => f.message) : apiResponse.access?.reason ? [apiResponse.access.reason] : ["Access denied"]),
|
|
358
420
|
failures: aggregatedFailures,
|
|
359
421
|
requiresStepUp: apiResponse.access?.requiresStepUp,
|
|
360
422
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
@@ -431,9 +493,7 @@ async function verify(config, request) {
|
|
|
431
493
|
if (result.recommendation === "deny") {
|
|
432
494
|
result.policyAllowed = false;
|
|
433
495
|
result.accessLevel = "none";
|
|
434
|
-
result.denialReasons = result.recommendationReasons
|
|
435
|
-
"Access denied by AstraSync recommendation"
|
|
436
|
-
];
|
|
496
|
+
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Access denied by AstraSync recommendation"];
|
|
437
497
|
result.guidance = result.runtimeChallenge ? {
|
|
438
498
|
message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
|
|
439
499
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
@@ -445,9 +505,10 @@ async function verify(config, request) {
|
|
|
445
505
|
};
|
|
446
506
|
} else if (result.recommendation === "step_up_required") {
|
|
447
507
|
result.requiresStepUp = true;
|
|
448
|
-
result.denialReasons = result.recommendationReasons
|
|
508
|
+
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
|
|
449
509
|
}
|
|
450
|
-
|
|
510
|
+
const escalates = result.requiresStepUp === true || result.requiresApproval === true || result.recommendation === "step_up_required";
|
|
511
|
+
if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny" && !escalates) {
|
|
451
512
|
cacheResult(request, result, mergedConfig.cacheTtl, mergedConfig.counterpartyId);
|
|
452
513
|
}
|
|
453
514
|
return result;
|
|
@@ -1008,7 +1069,7 @@ function createMiddleware(options) {
|
|
|
1008
1069
|
}
|
|
1009
1070
|
const forwardedFor = request.headers.get("x-forwarded-for") || void 0;
|
|
1010
1071
|
const originalClientIp = forwardedFor?.split(",")[0]?.trim();
|
|
1011
|
-
const
|
|
1072
|
+
const verificationRequest = {
|
|
1012
1073
|
credentials,
|
|
1013
1074
|
purpose,
|
|
1014
1075
|
action: pdlssPair.action,
|
|
@@ -1025,7 +1086,17 @@ function createMiddleware(options) {
|
|
|
1025
1086
|
forwardedFor,
|
|
1026
1087
|
agentCardUrl: request.headers.get("x-astrasync-agent-card") || void 0
|
|
1027
1088
|
}
|
|
1028
|
-
}
|
|
1089
|
+
};
|
|
1090
|
+
let result = await verify(config, verificationRequest);
|
|
1091
|
+
let stepUpHoldOutcome;
|
|
1092
|
+
if (config.stepUpMaxWaitMs !== void 0 && result.identityVerified && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
|
|
1093
|
+
stepUpHoldOutcome = await awaitStepUpApproval(config, result.stepUpApproval);
|
|
1094
|
+
if (stepUpHoldOutcome === "approved") {
|
|
1095
|
+
result = await verify(config, verificationRequest, { bypassCache: true });
|
|
1096
|
+
} else {
|
|
1097
|
+
result.stepUpOutcome = stepUpHoldOutcome;
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1029
1100
|
const approvalRequired = result.identityVerified && result.policyAllowed && requiresHumanApproval(result);
|
|
1030
1101
|
if (approvalRequired) annotateApprovalRequired(result);
|
|
1031
1102
|
if (!result.identityVerified || !result.policyAllowed || approvalRequired) {
|
|
@@ -1040,10 +1111,17 @@ function createMiddleware(options) {
|
|
|
1040
1111
|
message: result.denialReasons?.[0] || "Access denied",
|
|
1041
1112
|
guidance: result.guidance,
|
|
1042
1113
|
failures: result.failures,
|
|
1043
|
-
stepUpApproval: result.stepUpApproval
|
|
1114
|
+
stepUpApproval: result.stepUpApproval,
|
|
1115
|
+
// 3.6.0: terminal outcome of an opt-in hold-and-poll wait.
|
|
1116
|
+
...result.stepUpOutcome && { stepUpOutcome: result.stepUpOutcome }
|
|
1044
1117
|
}
|
|
1045
1118
|
},
|
|
1046
|
-
{
|
|
1119
|
+
{
|
|
1120
|
+
status: !result.identityVerified ? 401 : 403,
|
|
1121
|
+
...stepUpHoldOutcome && {
|
|
1122
|
+
headers: { "X-Astra-Step-Up": stepUpHoldOutcome }
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1047
1125
|
);
|
|
1048
1126
|
}
|
|
1049
1127
|
if (showCommerceShield) {
|
|
@@ -1062,6 +1140,9 @@ function createMiddleware(options) {
|
|
|
1062
1140
|
"X-AstraSync-Verified",
|
|
1063
1141
|
(result.identityVerified && result.policyAllowed).toString()
|
|
1064
1142
|
);
|
|
1143
|
+
if (stepUpHoldOutcome) {
|
|
1144
|
+
response.headers.set("X-Astra-Step-Up", stepUpHoldOutcome);
|
|
1145
|
+
}
|
|
1065
1146
|
response.headers.set("X-AstraSync-Identity-Verified", result.identityVerified.toString());
|
|
1066
1147
|
response.headers.set("X-AstraSync-Policy-Allowed", result.policyAllowed.toString());
|
|
1067
1148
|
response.headers.set("X-AstraSync-Access-Level", result.accessLevel);
|