@astrasyncai/verification-gateway 4.3.0 → 4.4.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/adapters/express.js +91 -19
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +91 -19
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.js +52 -13
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +52 -13
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.js +89 -17
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +89 -17
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.js +24 -6
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +24 -6
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.js +24 -3
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +24 -3
- package/dist/agent/index.mjs.map +1 -1
- package/dist/bin/astrasync-claude-hook.js +22 -4
- package/dist/bin/astrasync-codex-hook.js +22 -4
- package/dist/bin/astrasync-guard.js +26 -8
- package/dist/bin/astrasync.js +66 -23
- package/dist/browser/background.js +22 -4
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +22 -4
- package/dist/browser/background.mjs.map +1 -1
- package/dist/cli/index.js +23 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +23 -2
- package/dist/cli/index.mjs.map +1 -1
- package/dist/codex/index.js +22 -4
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +22 -4
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +22 -4
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +22 -4
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.js +24 -1
- package/dist/edge-config.js.map +1 -1
- package/dist/edge-config.mjs +22 -1
- package/dist/edge-config.mjs.map +1 -1
- package/dist/edge-core/index.js +96 -11
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +96 -11
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +22 -4
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +22 -4
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/index.d.mts +51 -2
- package/dist/index.d.ts +51 -2
- package/dist/index.js +151 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +147 -26
- package/dist/index.mjs.map +1 -1
- package/dist/metadata-capture.d.mts +17 -0
- package/dist/metadata-capture.d.ts +17 -0
- package/dist/metadata-capture.js +25 -4
- package/dist/metadata-capture.js.map +1 -1
- package/dist/metadata-capture.mjs +25 -4
- package/dist/metadata-capture.mjs.map +1 -1
- package/dist/platform-signatures.d.mts +18 -1
- package/dist/platform-signatures.d.ts +18 -1
- package/dist/platform-signatures.js +35 -2
- package/dist/platform-signatures.js.map +1 -1
- package/dist/platform-signatures.mjs +35 -2
- package/dist/platform-signatures.mjs.map +1 -1
- package/dist/registration/index.js +25 -4
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +25 -4
- package/dist/registration/index.mjs.map +1 -1
- package/dist/transport/index.js +22 -1
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +22 -1
- package/dist/transport/index.mjs.map +1 -1
- package/dist/verify.js +29 -11
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +29 -11
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
package/dist/adapters/express.js
CHANGED
|
@@ -25,6 +25,27 @@ __export(express_exports, {
|
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(express_exports);
|
|
27
27
|
|
|
28
|
+
// src/version.ts
|
|
29
|
+
var SDK_VERSION = "4.4.0";
|
|
30
|
+
|
|
31
|
+
// src/http.ts
|
|
32
|
+
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
33
|
+
function withUserAgent(initHeaders) {
|
|
34
|
+
if (!initHeaders) return { "user-agent": SDK_USER_AGENT };
|
|
35
|
+
if (initHeaders instanceof Headers) {
|
|
36
|
+
const copy = new Headers(initHeaders);
|
|
37
|
+
if (!copy.has("user-agent")) copy.set("user-agent", SDK_USER_AGENT);
|
|
38
|
+
return copy;
|
|
39
|
+
}
|
|
40
|
+
if (Array.isArray(initHeaders)) {
|
|
41
|
+
const has2 = initHeaders.some(([name]) => name.toLowerCase() === "user-agent");
|
|
42
|
+
return has2 ? initHeaders : [...initHeaders, ["user-agent", SDK_USER_AGENT]];
|
|
43
|
+
}
|
|
44
|
+
const has = Object.keys(initHeaders).some((name) => name.toLowerCase() === "user-agent");
|
|
45
|
+
return has ? initHeaders : { "user-agent": SDK_USER_AGENT, ...initHeaders };
|
|
46
|
+
}
|
|
47
|
+
var sdkFetch = (input, init) => fetch(input, { ...init, headers: withUserAgent(init?.headers) });
|
|
48
|
+
|
|
28
49
|
// src/adapters/stepup-poll.ts
|
|
29
50
|
var DEFAULT_POLL_INTERVAL_MS = 3e3;
|
|
30
51
|
var MIN_POLL_INTERVAL_MS = 250;
|
|
@@ -39,7 +60,7 @@ function resolvePollUrl(config, pollUrl) {
|
|
|
39
60
|
async function pollStepUpStatus(config, approval) {
|
|
40
61
|
if (!approval.pollUrl) return null;
|
|
41
62
|
try {
|
|
42
|
-
const res = await
|
|
63
|
+
const res = await sdkFetch(resolvePollUrl(config, approval.pollUrl), {
|
|
43
64
|
method: "GET",
|
|
44
65
|
signal: AbortSignal.timeout(POLL_REQUEST_TIMEOUT_MS)
|
|
45
66
|
});
|
|
@@ -91,9 +112,6 @@ function getTrustLevel(score) {
|
|
|
91
112
|
return "BRONZE";
|
|
92
113
|
}
|
|
93
114
|
|
|
94
|
-
// src/version.ts
|
|
95
|
-
var SDK_VERSION = "4.1.0";
|
|
96
|
-
|
|
97
115
|
// src/well-known.ts
|
|
98
116
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
99
117
|
var cache = /* @__PURE__ */ new Map();
|
|
@@ -104,7 +122,7 @@ function wellKnownUrl(apiBaseUrl) {
|
|
|
104
122
|
}
|
|
105
123
|
async function fetchWellKnown(apiBaseUrl) {
|
|
106
124
|
const url = wellKnownUrl(apiBaseUrl);
|
|
107
|
-
const response = await
|
|
125
|
+
const response = await sdkFetch(url, {
|
|
108
126
|
method: "GET",
|
|
109
127
|
headers: { Accept: "application/json" },
|
|
110
128
|
signal: AbortSignal.timeout(5e3)
|
|
@@ -174,7 +192,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
174
192
|
initCheckPerformed = true;
|
|
175
193
|
try {
|
|
176
194
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
177
|
-
const response = await
|
|
195
|
+
const response = await sdkFetch(probeUrl, { method: "HEAD" });
|
|
178
196
|
const contentType = response.headers.get("content-type") ?? "";
|
|
179
197
|
if (contentType.startsWith("text/html")) {
|
|
180
198
|
const message = `[VerificationGateway] apiBaseUrl '${apiBaseUrl}' returned HTML (content-type: ${contentType}). This usually means apiBaseUrl is pointing at a marketing site instead of the API. Expected: 'https://astrasync.ai/api' (prod) or 'https://staging.astrasync.ai/api' (staging).`;
|
|
@@ -188,7 +206,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
188
206
|
);
|
|
189
207
|
}
|
|
190
208
|
if (apiKey) {
|
|
191
|
-
const selfCheck = await
|
|
209
|
+
const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
|
|
192
210
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
193
211
|
});
|
|
194
212
|
if (selfCheck.status === 401) {
|
|
@@ -435,7 +453,7 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
435
453
|
headers["X-API-Key"] = config.apiKey;
|
|
436
454
|
}
|
|
437
455
|
try {
|
|
438
|
-
const response = await
|
|
456
|
+
const response = await sdkFetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
439
457
|
method: "POST",
|
|
440
458
|
headers,
|
|
441
459
|
body: JSON.stringify(body),
|
|
@@ -678,7 +696,7 @@ async function recordDecision(config, sessionId, decision, reason) {
|
|
|
678
696
|
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
679
697
|
headers["X-API-Key"] = config.apiKey;
|
|
680
698
|
}
|
|
681
|
-
await
|
|
699
|
+
await sdkFetch(`${config.apiBaseUrl}/agents/verify-access/${sessionId}/decision`, {
|
|
682
700
|
method: "POST",
|
|
683
701
|
headers,
|
|
684
702
|
body: JSON.stringify({ decision, reason })
|
|
@@ -693,7 +711,7 @@ async function fetchRoutes(config, counterpartyId) {
|
|
|
693
711
|
headers["X-API-Key"] = config.apiKey;
|
|
694
712
|
}
|
|
695
713
|
try {
|
|
696
|
-
const response = await
|
|
714
|
+
const response = await sdkFetch(
|
|
697
715
|
`${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/routes`,
|
|
698
716
|
{ method: "GET", headers }
|
|
699
717
|
);
|
|
@@ -712,7 +730,7 @@ async function reportUnregisteredAttempt(config, data) {
|
|
|
712
730
|
...counterpartyUrl && { counterpartyUrl },
|
|
713
731
|
...config.counterpartyId && { counterpartyId: config.counterpartyId }
|
|
714
732
|
};
|
|
715
|
-
await
|
|
733
|
+
await sdkFetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
|
|
716
734
|
method: "POST",
|
|
717
735
|
headers: { "Content-Type": "application/json" },
|
|
718
736
|
body: JSON.stringify(body)
|
|
@@ -721,7 +739,7 @@ async function reportUnregisteredAttempt(config, data) {
|
|
|
721
739
|
}
|
|
722
740
|
async function reportCounterpartyPreCheckFailure(config, data) {
|
|
723
741
|
const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
|
|
724
|
-
await
|
|
742
|
+
await sdkFetch(`${apiBaseUrl}/verification-activity/counterparty-pre-check-failure`, {
|
|
725
743
|
method: "POST",
|
|
726
744
|
headers: { "Content-Type": "application/json" },
|
|
727
745
|
body: JSON.stringify(data)
|
|
@@ -977,7 +995,13 @@ var PLATFORM_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
|
977
995
|
"x-agent-card-url",
|
|
978
996
|
"x-agent-provider"
|
|
979
997
|
]);
|
|
980
|
-
var PLATFORM_HEADER_PREFIXES = [
|
|
998
|
+
var PLATFORM_HEADER_PREFIXES = [
|
|
999
|
+
"x-goog-",
|
|
1000
|
+
"x-stainless-",
|
|
1001
|
+
"x-anthropic-",
|
|
1002
|
+
"x-openai-",
|
|
1003
|
+
"sec-ch-"
|
|
1004
|
+
];
|
|
981
1005
|
var KEY_FORMAT_PREFIXES = [
|
|
982
1006
|
"sk-ant-api03",
|
|
983
1007
|
"sk-ant-api",
|
|
@@ -1049,6 +1073,7 @@ function sanitizeHeaders(raw) {
|
|
|
1049
1073
|
const headers = {};
|
|
1050
1074
|
const platformHeaders = {};
|
|
1051
1075
|
let apiKeyFormat;
|
|
1076
|
+
let cookieCount;
|
|
1052
1077
|
let totalBytes = 0;
|
|
1053
1078
|
let count = 0;
|
|
1054
1079
|
if (!raw) return { headers };
|
|
@@ -1063,6 +1088,9 @@ function sanitizeHeaders(raw) {
|
|
|
1063
1088
|
if (fmt && !apiKeyFormat) apiKeyFormat = fmt;
|
|
1064
1089
|
continue;
|
|
1065
1090
|
}
|
|
1091
|
+
if (name === "cookie") {
|
|
1092
|
+
cookieCount = joined.split(";").filter((s) => s.trim().length > 0).length;
|
|
1093
|
+
}
|
|
1066
1094
|
if (isSecretHeader(name)) continue;
|
|
1067
1095
|
let value = joined;
|
|
1068
1096
|
if (byteLength(value) > MAX_HEADER_VALUE_BYTES) {
|
|
@@ -1078,6 +1106,7 @@ function sanitizeHeaders(raw) {
|
|
|
1078
1106
|
const result = { headers };
|
|
1079
1107
|
if (apiKeyFormat) result.apiKeyFormat = apiKeyFormat;
|
|
1080
1108
|
if (Object.keys(platformHeaders).length > 0) result.platformHeaders = platformHeaders;
|
|
1109
|
+
if (cookieCount !== void 0) result.cookieCount = cookieCount;
|
|
1081
1110
|
return result;
|
|
1082
1111
|
}
|
|
1083
1112
|
var CONNECTION_HEADER_SOURCES = [
|
|
@@ -1089,6 +1118,9 @@ var CONNECTION_HEADER_SOURCES = [
|
|
|
1089
1118
|
["region", ["x-vercel-ip-country-region", "cloudfront-viewer-country-region"]],
|
|
1090
1119
|
["countryRegionName", ["cloudfront-viewer-country-region-name"]],
|
|
1091
1120
|
["city", ["x-vercel-ip-city", "cloudfront-viewer-city"]],
|
|
1121
|
+
["latitude", ["x-vercel-ip-latitude", "cloudfront-viewer-latitude"]],
|
|
1122
|
+
["longitude", ["x-vercel-ip-longitude", "cloudfront-viewer-longitude"]],
|
|
1123
|
+
["postalCode", ["x-vercel-ip-postal-code", "cloudfront-viewer-postal-code"]],
|
|
1092
1124
|
["asn", ["cloudfront-viewer-asn"]],
|
|
1093
1125
|
["tlsVersion", ["cloudfront-viewer-tls"]],
|
|
1094
1126
|
["httpVersion", ["cloudfront-viewer-http-version"]],
|
|
@@ -1123,19 +1155,25 @@ function deriveConnectionFromHeaders(headers) {
|
|
|
1123
1155
|
}
|
|
1124
1156
|
}
|
|
1125
1157
|
}
|
|
1126
|
-
|
|
1158
|
+
{
|
|
1127
1159
|
const addr = lower["cloudfront-viewer-address"]?.trim();
|
|
1128
|
-
|
|
1160
|
+
const portMatch = addr?.match(/:(\d+)$/);
|
|
1161
|
+
if (portMatch) connection.sourcePort = portMatch[1];
|
|
1162
|
+
if (!connection.ip && addr) connection.ip = addr.replace(/:\d+$/, "");
|
|
1129
1163
|
}
|
|
1130
1164
|
if (!connection.ip) {
|
|
1131
1165
|
const xff = lower["x-forwarded-for"];
|
|
1132
1166
|
const client = xff?.split(",")[0]?.trim();
|
|
1133
1167
|
if (client) connection.ip = client;
|
|
1134
1168
|
}
|
|
1169
|
+
if (!connection.tlsCipher) {
|
|
1170
|
+
const cipher = connection.tlsVersion?.split(":")[1];
|
|
1171
|
+
if (cipher) connection.tlsCipher = cipher;
|
|
1172
|
+
}
|
|
1135
1173
|
return Object.keys(connection).length > 0 ? connection : void 0;
|
|
1136
1174
|
}
|
|
1137
1175
|
function buildSdkObservedMetadata(rawHeaders) {
|
|
1138
|
-
const { headers, apiKeyFormat, platformHeaders } = sanitizeHeaders(rawHeaders);
|
|
1176
|
+
const { headers, apiKeyFormat, platformHeaders, cookieCount } = sanitizeHeaders(rawHeaders);
|
|
1139
1177
|
const flat = {};
|
|
1140
1178
|
if (rawHeaders) {
|
|
1141
1179
|
for (const name of Object.keys(rawHeaders)) {
|
|
@@ -1150,6 +1188,7 @@ function buildSdkObservedMetadata(rawHeaders) {
|
|
|
1150
1188
|
...apiKeyFormat && { apiKeyFormat },
|
|
1151
1189
|
...platformHeaders && { platformHeaders },
|
|
1152
1190
|
...connection && { connection },
|
|
1191
|
+
...cookieCount !== void 0 && { cookieCount },
|
|
1153
1192
|
schemaVersion: CAPTURE_SCHEMA_VERSION
|
|
1154
1193
|
};
|
|
1155
1194
|
}
|
|
@@ -1194,7 +1233,7 @@ async function fetchEdgeConfig(config, counterpartyId, opts) {
|
|
|
1194
1233
|
}
|
|
1195
1234
|
if (opts?.etag) headers["If-None-Match"] = opts.etag;
|
|
1196
1235
|
try {
|
|
1197
|
-
const response = await
|
|
1236
|
+
const response = await sdkFetch(
|
|
1198
1237
|
`${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/edge-config`,
|
|
1199
1238
|
{ method: "GET", headers, signal: AbortSignal.timeout(opts?.timeoutMs ?? 5e3) }
|
|
1200
1239
|
);
|
|
@@ -1306,12 +1345,43 @@ var PLATFORM_AGENT_SIGNATURES = [
|
|
|
1306
1345
|
uaPatterns: [/perplexity/i],
|
|
1307
1346
|
agentCardPatterns: [/perplexity\.ai/i],
|
|
1308
1347
|
apiKeyFormatPatterns: [/^pplx-/i]
|
|
1348
|
+
},
|
|
1349
|
+
// Agentic browsers — versioned-token patterns ONLY (a stock Chrome UA must
|
|
1350
|
+
// never match). Distinct vendor keys (not 'chatgpt'/'perplexity'): the
|
|
1351
|
+
// browser product is a different surface than the assistant service, and
|
|
1352
|
+
// the DB registry mirrors one row per vendor. These sit after the primary
|
|
1353
|
+
// vendor entries so a UA carrying an explicit vendor token keeps its
|
|
1354
|
+
// primary attribution; a browser-shaped UA with the agentic token is
|
|
1355
|
+
// caught here BEFORE classify's human tier, which is what makes these
|
|
1356
|
+
// visits observable at all. Token drift is real (some builds mimic Chrome
|
|
1357
|
+
// outright) — re-verify against captured events when a new browser ships,
|
|
1358
|
+
// and check `sec-ch-ua` platformHeaders for the real brand.
|
|
1359
|
+
{
|
|
1360
|
+
vendor: "chatgpt-atlas",
|
|
1361
|
+
displayName: "ChatGPT Atlas browser",
|
|
1362
|
+
uaPatterns: [/\batlas\/\d/i],
|
|
1363
|
+
headerPatterns: [/^sec-ch-ua: .*atlas/i]
|
|
1364
|
+
},
|
|
1365
|
+
{
|
|
1366
|
+
vendor: "perplexity-comet",
|
|
1367
|
+
displayName: "Perplexity Comet browser",
|
|
1368
|
+
uaPatterns: [/\bcomet\/\d/i],
|
|
1369
|
+
headerPatterns: [/^sec-ch-ua: .*comet/i]
|
|
1370
|
+
},
|
|
1371
|
+
// Our own SDK self-identifies (sdkFetch stamps this UA) — first-party
|
|
1372
|
+
// traffic must never pollute the unknown/anonymous pool it exists to audit.
|
|
1373
|
+
{
|
|
1374
|
+
vendor: "astrasync-sdk",
|
|
1375
|
+
displayName: "AstraSync SDK",
|
|
1376
|
+
uaPatterns: [/^astrasync-sdk\//i]
|
|
1309
1377
|
}
|
|
1310
1378
|
];
|
|
1311
1379
|
function matchPlatformSignature(signatures, input) {
|
|
1312
1380
|
const ua = input.userAgent ?? "";
|
|
1313
1381
|
const cardUrl = input.agentCardUrl ?? "";
|
|
1314
1382
|
const apiKeyFormat = input.apiKeyFormat ?? "";
|
|
1383
|
+
const ja4 = input.ja4 ?? "";
|
|
1384
|
+
const asn = input.asn ?? "";
|
|
1315
1385
|
const headerLines = [];
|
|
1316
1386
|
if (input.platformHeaders) {
|
|
1317
1387
|
for (const [name, value] of Object.entries(input.platformHeaders)) {
|
|
@@ -1323,7 +1393,9 @@ function matchPlatformSignature(signatures, input) {
|
|
|
1323
1393
|
const cardMatch = sig.agentCardPatterns?.some((p) => p.test(cardUrl));
|
|
1324
1394
|
const keyMatch = apiKeyFormat.length > 0 && sig.apiKeyFormatPatterns?.some((p) => p.test(apiKeyFormat));
|
|
1325
1395
|
const headerMatch = headerLines.length > 0 && sig.headerPatterns?.some((p) => headerLines.some((line) => p.test(line)));
|
|
1326
|
-
|
|
1396
|
+
const ja4Match = ja4.length > 0 && sig.ja4Patterns?.some((p) => p.test(ja4));
|
|
1397
|
+
const asnMatch = asn.length > 0 && sig.asnList?.includes(asn);
|
|
1398
|
+
if (uaMatch || cardMatch || keyMatch || headerMatch || ja4Match || asnMatch) {
|
|
1327
1399
|
const uaBase = ua.split(/[\s/]/)[0]?.toLowerCase() ?? "";
|
|
1328
1400
|
const cardHost = (() => {
|
|
1329
1401
|
try {
|
|
@@ -1332,7 +1404,7 @@ function matchPlatformSignature(signatures, input) {
|
|
|
1332
1404
|
return "";
|
|
1333
1405
|
}
|
|
1334
1406
|
})();
|
|
1335
|
-
const keyBasis = uaBase || cardHost || apiKeyFormat || "unknown";
|
|
1407
|
+
const keyBasis = uaBase || cardHost || apiKeyFormat || ja4 || asn && `asn${asn}` || "unknown";
|
|
1336
1408
|
return {
|
|
1337
1409
|
vendor: sig.vendor,
|
|
1338
1410
|
fingerprintKey: `${sig.vendor}:${keyBasis}`,
|