@astrasyncai/verification-gateway 2.3.4 → 2.3.8
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 +101 -22
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +100 -19
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +245 -0
- package/dist/adapters/mcp.d.ts +245 -0
- package/dist/adapters/mcp.js +619 -0
- package/dist/adapters/mcp.js.map +1 -0
- package/dist/adapters/mcp.mjs +585 -0
- package/dist/adapters/mcp.mjs.map +1 -0
- package/dist/adapters/nextjs.d.mts +2 -2
- package/dist/adapters/nextjs.d.ts +2 -2
- package/dist/adapters/nextjs.js +76 -4
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +76 -4
- 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 +22 -2
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +22 -2
- 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 +28 -2
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +28 -2
- 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 +28 -2
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +28 -2
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/{express-DtvJ6BGt.d.mts → express-BNWqDVIz.d.mts} +17 -14
- package/dist/{express-CraCA8_t.d.ts → express-BYup_4Jg.d.ts} +17 -14
- package/dist/gateway/gateway.d.mts +2 -2
- package/dist/gateway/gateway.d.ts +2 -2
- package/dist/gateway/gateway.js +28 -2
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +28 -2
- 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-SEgnWzkf.d.mts → index-BHXa2WTO.d.mts} +1 -1
- package/dist/{index-BZ85CeEr.d.mts → index-CK4lNLVn.d.mts} +1 -1
- package/dist/{index--KzVRa32.d.ts → index-CSMpOcxV.d.ts} +1 -1
- package/dist/{index-BzAFmemy.d.ts → index-DN3ztP2d.d.ts} +1 -1
- package/dist/index.d.mts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +135 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +135 -21
- 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-DZHAn9j-.d.mts → nextjs-Bzdfu8Eg.d.mts} +8 -2
- package/dist/{nextjs-B8o9C0t6.d.ts → nextjs-C4h_MpgK.d.ts} +8 -2
- package/dist/{sdk-CRSUFQH2.d.mts → sdk-CDdD7EcJ.d.mts} +1 -1
- package/dist/{sdk-BQ3olp3v.d.ts → sdk-Tzsn6s-O.d.ts} +1 -1
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/{types-osMd_dpT.d.ts → types-Bzp1SMaD.d.ts} +1 -1
- package/dist/{types-JMgPake9.d.mts → types-D_tmbDA_.d.mts} +75 -7
- package/dist/{types-JMgPake9.d.ts → types-D_tmbDA_.d.ts} +75 -7
- package/dist/{types-aN1UHhyy.d.mts → types-z-QVnG4b.d.mts} +1 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/package.json +6 -1
package/dist/index.mjs
CHANGED
|
@@ -284,6 +284,23 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
284
284
|
body: JSON.stringify(body)
|
|
285
285
|
});
|
|
286
286
|
const data = await response.json();
|
|
287
|
+
if (response.status === 410) {
|
|
288
|
+
return {
|
|
289
|
+
success: true,
|
|
290
|
+
access: {
|
|
291
|
+
allowed: false,
|
|
292
|
+
accessLevel: "none",
|
|
293
|
+
reason: "endpoint_deactivated",
|
|
294
|
+
failures: [
|
|
295
|
+
{
|
|
296
|
+
dimension: "endpoint.deactivated",
|
|
297
|
+
message: typeof data?.message === "string" ? data.message : "Endpoint has been deactivated",
|
|
298
|
+
guidance: typeof data?.guidance === "string" ? data.guidance : "Reactivate via POST /api/endpoints/{id}/reactivate, or update the URL on the calling agent."
|
|
299
|
+
}
|
|
300
|
+
]
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
}
|
|
287
304
|
if (!response.ok) {
|
|
288
305
|
return {
|
|
289
306
|
success: false,
|
|
@@ -334,10 +351,12 @@ async function verify(config, request) {
|
|
|
334
351
|
return createGuidanceResponse(mergedConfig, apiResponse.error);
|
|
335
352
|
}
|
|
336
353
|
if (!apiResponse.access?.allowed) {
|
|
354
|
+
const aggregatedFailures = apiResponse.access?.failures;
|
|
337
355
|
const result2 = {
|
|
338
356
|
verified: false,
|
|
339
357
|
accessLevel: "guidance",
|
|
340
|
-
denialReasons: apiResponse.access?.reason ? [apiResponse.access.reason] : ["Access denied"],
|
|
358
|
+
denialReasons: aggregatedFailures && aggregatedFailures.length > 0 ? aggregatedFailures.map((f) => f.message) : apiResponse.access?.reason ? [apiResponse.access.reason] : ["Access denied"],
|
|
359
|
+
failures: aggregatedFailures,
|
|
341
360
|
requiresStepUp: apiResponse.access?.requiresStepUp,
|
|
342
361
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
343
362
|
guidance: {
|
|
@@ -391,7 +410,8 @@ async function verify(config, request) {
|
|
|
391
410
|
runtimeChallenge: apiResponse.runtimeChallenge,
|
|
392
411
|
tokenGuidance: apiResponse.tokenGuidance,
|
|
393
412
|
recommendation: apiResponse.recommendation,
|
|
394
|
-
recommendationReasons: apiResponse.recommendationReasons
|
|
413
|
+
recommendationReasons: apiResponse.recommendationReasons,
|
|
414
|
+
warningHeader: apiResponse.warningHeader
|
|
395
415
|
};
|
|
396
416
|
if (result.recommendation === "deny") {
|
|
397
417
|
result.verified = false;
|
|
@@ -431,6 +451,25 @@ async function recordDecision(config, sessionId, decision, reason) {
|
|
|
431
451
|
}).catch(() => {
|
|
432
452
|
});
|
|
433
453
|
}
|
|
454
|
+
async function fetchRoutes(config, counterpartyId) {
|
|
455
|
+
if (!counterpartyId) return null;
|
|
456
|
+
const headers = { "Content-Type": "application/json" };
|
|
457
|
+
if (config.apiKey) {
|
|
458
|
+
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
459
|
+
headers["X-API-Key"] = config.apiKey;
|
|
460
|
+
}
|
|
461
|
+
try {
|
|
462
|
+
const response = await fetch(
|
|
463
|
+
`${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/routes`,
|
|
464
|
+
{ method: "GET", headers }
|
|
465
|
+
);
|
|
466
|
+
if (!response.ok) return null;
|
|
467
|
+
const body = await response.json();
|
|
468
|
+
return body.data?.routes ?? [];
|
|
469
|
+
} catch {
|
|
470
|
+
return null;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
434
473
|
async function reportCounterpartyPreCheckFailure(config, data) {
|
|
435
474
|
const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
|
|
436
475
|
await fetch(`${apiBaseUrl}/verification-activity/counterparty-pre-check-failure`, {
|
|
@@ -456,9 +495,7 @@ async function quickVerify(config, credentials) {
|
|
|
456
495
|
var express_exports = {};
|
|
457
496
|
__export(express_exports, {
|
|
458
497
|
createMiddleware: () => createMiddleware,
|
|
459
|
-
extractAstraSyncCredentials: () => extractAstraSyncCredentials
|
|
460
|
-
requireAccess: () => requireAccess,
|
|
461
|
-
verifyOnly: () => verifyOnly
|
|
498
|
+
extractAstraSyncCredentials: () => extractAstraSyncCredentials
|
|
462
499
|
});
|
|
463
500
|
|
|
464
501
|
// src/transport/http.ts
|
|
@@ -631,28 +668,80 @@ function defaultOnDenied(result, _req, res) {
|
|
|
631
668
|
}
|
|
632
669
|
});
|
|
633
670
|
}
|
|
671
|
+
var DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
|
|
634
672
|
function createMiddleware(options) {
|
|
635
673
|
const {
|
|
636
|
-
routes = [],
|
|
637
674
|
extractCredentials: customExtractCredentials,
|
|
638
675
|
extractPurpose: customExtractPurpose,
|
|
639
676
|
skipPaths = [],
|
|
640
677
|
onDenied = defaultOnDenied,
|
|
641
678
|
recordDecisions,
|
|
642
679
|
enableRuntimeChallenge = true,
|
|
680
|
+
routesRefreshMs = DEFAULT_ROUTES_REFRESH_MS,
|
|
643
681
|
...config
|
|
644
682
|
} = options;
|
|
683
|
+
let cachedRoutes = [];
|
|
684
|
+
let lastFetchAt = 0;
|
|
685
|
+
let refreshing = null;
|
|
686
|
+
let warnedNoCounterparty = false;
|
|
687
|
+
let warnedEmptyRoutes = false;
|
|
688
|
+
async function refreshRoutes() {
|
|
689
|
+
if (!config.counterpartyId) {
|
|
690
|
+
if (!warnedNoCounterparty) {
|
|
691
|
+
console.warn(
|
|
692
|
+
"[VerificationGateway] No counterpartyId configured \u2014 falling through (allow all). Per-route policy lives in the AstraSync dashboard now; register the endpoint and set counterpartyId in your middleware config to enforce policy."
|
|
693
|
+
);
|
|
694
|
+
warnedNoCounterparty = true;
|
|
695
|
+
}
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
const fetched = await fetchRoutes(config, config.counterpartyId);
|
|
699
|
+
if (fetched) {
|
|
700
|
+
cachedRoutes = fetched;
|
|
701
|
+
lastFetchAt = Date.now();
|
|
702
|
+
if (cachedRoutes.length === 0 && !warnedEmptyRoutes) {
|
|
703
|
+
const dashboard = config.dashboardUrl ?? "https://app.astrasync.ai";
|
|
704
|
+
console.warn(
|
|
705
|
+
`[VerificationGateway] No route policy configured for ${config.counterpartyId}. Gateway is in pass-through mode for ALL traffic until you add at least one route. Configure at ${dashboard}/dashboard/endpoints/${config.counterpartyId}/routes`
|
|
706
|
+
);
|
|
707
|
+
warnedEmptyRoutes = true;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
refreshing = refreshRoutes().finally(() => {
|
|
712
|
+
refreshing = null;
|
|
713
|
+
});
|
|
645
714
|
return async (req, res, next) => {
|
|
646
715
|
try {
|
|
647
716
|
const shouldSkip = skipPaths.some((pattern) => matchRoute(pattern, req.path));
|
|
648
717
|
if (shouldSkip) {
|
|
649
718
|
return next();
|
|
650
719
|
}
|
|
651
|
-
|
|
720
|
+
if (refreshing) {
|
|
721
|
+
await refreshing.catch(() => {
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
if (config.counterpartyId && Date.now() - lastFetchAt > routesRefreshMs) {
|
|
725
|
+
refreshing = refreshRoutes().finally(() => {
|
|
726
|
+
refreshing = null;
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
const routeConfig = findRouteConfig(cachedRoutes, req.path, req.method);
|
|
652
730
|
if (!routeConfig) {
|
|
731
|
+
if (config.setPassThroughHeader) {
|
|
732
|
+
res.setHeader("X-Astra-Gateway-Mode", "pass-through");
|
|
733
|
+
res.setHeader(
|
|
734
|
+
"X-Astra-Gateway-Reason",
|
|
735
|
+
cachedRoutes.length === 0 ? "no-policy" : "no-match"
|
|
736
|
+
);
|
|
737
|
+
}
|
|
653
738
|
return next();
|
|
654
739
|
}
|
|
655
740
|
if (routeConfig.minAccessLevel === "none") {
|
|
741
|
+
if (config.setPassThroughHeader) {
|
|
742
|
+
res.setHeader("X-Astra-Gateway-Mode", "pass-through");
|
|
743
|
+
res.setHeader("X-Astra-Gateway-Reason", "route-none");
|
|
744
|
+
}
|
|
656
745
|
return next();
|
|
657
746
|
}
|
|
658
747
|
const credentials = customExtractCredentials ? customExtractCredentials(req) : defaultExtractCredentials(req);
|
|
@@ -736,6 +825,10 @@ function createMiddleware(options) {
|
|
|
736
825
|
recordDecision(config, sessionId, "granted").catch(() => {
|
|
737
826
|
});
|
|
738
827
|
}
|
|
828
|
+
const enhancedResult = result;
|
|
829
|
+
if (enhancedResult.warningHeader) {
|
|
830
|
+
res.setHeader(enhancedResult.warningHeader.name, enhancedResult.warningHeader.value);
|
|
831
|
+
}
|
|
739
832
|
next();
|
|
740
833
|
} catch (error) {
|
|
741
834
|
console.error("[VerificationGateway] Middleware error:", error);
|
|
@@ -743,18 +836,6 @@ function createMiddleware(options) {
|
|
|
743
836
|
}
|
|
744
837
|
};
|
|
745
838
|
}
|
|
746
|
-
function requireAccess(minAccessLevel, options) {
|
|
747
|
-
return createMiddleware({
|
|
748
|
-
...options,
|
|
749
|
-
routes: [{ pattern: "*", method: "*", minAccessLevel }]
|
|
750
|
-
});
|
|
751
|
-
}
|
|
752
|
-
function verifyOnly(options) {
|
|
753
|
-
return createMiddleware({
|
|
754
|
-
...options,
|
|
755
|
-
routes: [{ pattern: "*", method: "*", minAccessLevel: "none" }]
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
839
|
|
|
759
840
|
// src/adapters/nextjs.ts
|
|
760
841
|
var nextjs_exports = {};
|
|
@@ -978,14 +1059,38 @@ function generateCommerceShieldHtml(result, options) {
|
|
|
978
1059
|
</html>
|
|
979
1060
|
`.trim();
|
|
980
1061
|
}
|
|
1062
|
+
var DEFAULT_ROUTES_REFRESH_MS2 = 5 * 60 * 1e3;
|
|
981
1063
|
function createMiddleware2(options) {
|
|
982
1064
|
const {
|
|
983
|
-
routes = [],
|
|
984
1065
|
skipPaths = [],
|
|
985
1066
|
showCommerceShield = true,
|
|
986
1067
|
enableRuntimeChallenge = true,
|
|
1068
|
+
routesRefreshMs = DEFAULT_ROUTES_REFRESH_MS2,
|
|
987
1069
|
...config
|
|
988
1070
|
} = options;
|
|
1071
|
+
let cachedRoutes = [];
|
|
1072
|
+
let lastFetchAt = 0;
|
|
1073
|
+
let refreshing = null;
|
|
1074
|
+
let warnedNoCounterparty = false;
|
|
1075
|
+
async function refreshRoutes() {
|
|
1076
|
+
if (!config.counterpartyId) {
|
|
1077
|
+
if (!warnedNoCounterparty) {
|
|
1078
|
+
console.warn(
|
|
1079
|
+
"[VerificationGateway/Next.js] No counterpartyId configured \u2014 falling through (allow all). Per-route policy lives in the AstraSync dashboard now; register the endpoint and set counterpartyId in your middleware config to enforce policy."
|
|
1080
|
+
);
|
|
1081
|
+
warnedNoCounterparty = true;
|
|
1082
|
+
}
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
const fetched = await fetchRoutes(config, config.counterpartyId);
|
|
1086
|
+
if (fetched) {
|
|
1087
|
+
cachedRoutes = fetched;
|
|
1088
|
+
lastFetchAt = Date.now();
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
refreshing = refreshRoutes().finally(() => {
|
|
1092
|
+
refreshing = null;
|
|
1093
|
+
});
|
|
989
1094
|
return async function middleware(request) {
|
|
990
1095
|
const { NextResponse } = await import("next/server");
|
|
991
1096
|
const pathname = request.nextUrl.pathname;
|
|
@@ -993,7 +1098,16 @@ function createMiddleware2(options) {
|
|
|
993
1098
|
if (shouldSkip) {
|
|
994
1099
|
return NextResponse.next();
|
|
995
1100
|
}
|
|
996
|
-
|
|
1101
|
+
if (refreshing) {
|
|
1102
|
+
await refreshing.catch(() => {
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1105
|
+
if (config.counterpartyId && Date.now() - lastFetchAt > routesRefreshMs) {
|
|
1106
|
+
refreshing = refreshRoutes().finally(() => {
|
|
1107
|
+
refreshing = null;
|
|
1108
|
+
});
|
|
1109
|
+
}
|
|
1110
|
+
const routeConfig = findRouteConfig2(cachedRoutes, pathname, request.method);
|
|
997
1111
|
if (!routeConfig) {
|
|
998
1112
|
return NextResponse.next();
|
|
999
1113
|
}
|