@astrasyncai/verification-gateway 5.11.0 → 5.13.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 +4 -0
- package/dist/adapters/express.d.mts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +394 -39
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +394 -39
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +5 -1
- package/dist/adapters/mcp.d.ts +5 -1
- package/dist/adapters/mcp.js +193 -49
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +193 -49
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +1 -1
- package/dist/adapters/nextjs.d.ts +1 -1
- package/dist/adapters/nextjs.js +387 -22
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +387 -22
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +9 -1
- package/dist/adapters/sdk.d.ts +9 -1
- package/dist/adapters/sdk.js +125 -16
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +125 -16
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.js +1 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +1 -1
- package/dist/agent/index.mjs.map +1 -1
- package/dist/bin/astrasync-claude-hook.js +309 -15
- package/dist/bin/astrasync-codex-hook.js +309 -15
- package/dist/bin/astrasync-guard.js +309 -15
- package/dist/bin/astrasync.js +322 -17
- package/dist/browser/background.js +309 -15
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +309 -15
- package/dist/browser/background.mjs.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/cli/index.mjs.map +1 -1
- package/dist/codex/index.js +309 -15
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +309 -15
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +309 -15
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +309 -15
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +1 -1
- package/dist/edge-config.d.ts +1 -1
- package/dist/edge-config.js +1 -1
- package/dist/edge-config.js.map +1 -1
- package/dist/edge-config.mjs +1 -1
- package/dist/edge-config.mjs.map +1 -1
- package/dist/edge-core/index.d.mts +128 -13
- package/dist/edge-core/index.d.ts +128 -13
- package/dist/edge-core/index.js +362 -63
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +359 -63
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +309 -15
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +309 -15
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +1 -1
- package/dist/git-trigger/git-hooks.d.ts +1 -1
- package/dist/index.d.mts +118 -15
- package/dist/index.d.ts +118 -15
- package/dist/index.js +521 -72
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +515 -72
- package/dist/index.mjs.map +1 -1
- package/dist/platform-signatures.js +4 -1
- package/dist/platform-signatures.js.map +1 -1
- package/dist/platform-signatures.mjs +4 -1
- package/dist/platform-signatures.mjs.map +1 -1
- package/dist/registration/index.js +1 -1
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +1 -1
- package/dist/registration/index.mjs.map +1 -1
- package/dist/transport/index.js +1 -1
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +1 -1
- package/dist/transport/index.mjs.map +1 -1
- package/dist/{types-CTmUpNpS.d.mts → types-BCkwBA84.d.mts} +12 -0
- package/dist/{types-CTmUpNpS.d.ts → types-BCkwBA84.d.ts} +12 -0
- package/dist/{types-CtFXmDzm.d.ts → types-C_b4QTyO.d.ts} +18 -0
- package/dist/{types-DQrn_kei.d.mts → types-DlshIIR-.d.mts} +18 -0
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +35 -14
- package/dist/verify.d.ts +35 -14
- package/dist/verify.js +165 -25
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +164 -25
- package/dist/verify.mjs.map +1 -1
- package/package.json +3 -2
package/dist/verify.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var SDK_VERSION = "5.
|
|
2
|
+
var SDK_VERSION = "5.13.0";
|
|
3
3
|
|
|
4
4
|
// src/http.ts
|
|
5
5
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -34,6 +34,29 @@ function getCachedWellKnownUrls(apiBaseUrl) {
|
|
|
34
34
|
return cache.get(apiBaseUrl)?.data;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
// src/failure-posture.ts
|
|
38
|
+
var DEFAULT_UNAVAILABLE_RETRY_AFTER_S = 30;
|
|
39
|
+
var REJECTED_IDENTITY_DIMENSIONS = /* @__PURE__ */ new Set([
|
|
40
|
+
"identity.invalid_agent_id",
|
|
41
|
+
"identity.unknown_agent",
|
|
42
|
+
"agent.lookup"
|
|
43
|
+
]);
|
|
44
|
+
var UNKNOWN_AGENT_GUIDANCE = "Register your agent with AstraSync (or, inside an MCP host, add the AstraSync MCP connector for keyless, human-approved registration), then present the canonical ASTRA-* id issued after owner approval.";
|
|
45
|
+
var UNAVAILABLE_DIMENSIONS = /* @__PURE__ */ new Set([
|
|
46
|
+
"verify_access.api_error",
|
|
47
|
+
"middleware.internal_error"
|
|
48
|
+
]);
|
|
49
|
+
function isVerificationUnavailable(result) {
|
|
50
|
+
if (result.misconfigured) return false;
|
|
51
|
+
return (result.failures ?? []).some((f) => UNAVAILABLE_DIMENSIONS.has(f.dimension));
|
|
52
|
+
}
|
|
53
|
+
function unavailableRetryAfterSeconds(result) {
|
|
54
|
+
if (typeof result.retryAfterMs === "number" && Number.isFinite(result.retryAfterMs)) {
|
|
55
|
+
return Math.max(1, Math.ceil(result.retryAfterMs / 1e3));
|
|
56
|
+
}
|
|
57
|
+
return DEFAULT_UNAVAILABLE_RETRY_AFTER_S;
|
|
58
|
+
}
|
|
59
|
+
|
|
37
60
|
// src/verify.ts
|
|
38
61
|
var DEFAULT_CONFIG = {
|
|
39
62
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
@@ -49,7 +72,7 @@ function _resetInitCheck() {
|
|
|
49
72
|
initCheckPerformed = false;
|
|
50
73
|
}
|
|
51
74
|
var deprecationWarningShown = false;
|
|
52
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
75
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey, counterparty) {
|
|
53
76
|
initCheckPerformed = true;
|
|
54
77
|
try {
|
|
55
78
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -67,7 +90,8 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
67
90
|
);
|
|
68
91
|
}
|
|
69
92
|
if (apiKey) {
|
|
70
|
-
const
|
|
93
|
+
const q = counterparty?.id ? `?counterpartyId=${encodeURIComponent(counterparty.id)}` : counterparty?.url ? `?counterpartyUrl=${encodeURIComponent(counterparty.url)}` : "";
|
|
94
|
+
const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check${q}`, {
|
|
71
95
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
72
96
|
});
|
|
73
97
|
if (selfCheck.status === 401) {
|
|
@@ -79,6 +103,13 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
79
103
|
console.error(message);
|
|
80
104
|
} else if (selfCheck.ok) {
|
|
81
105
|
const body = await selfCheck.json().catch(() => ({}));
|
|
106
|
+
if (body.counterparty && body.counterparty.canVerify === false) {
|
|
107
|
+
const message = `[VerificationGateway] the configured AstraSync API key cannot verify for this endpoint (${body.counterparty.message ?? "endpoint not found or owned by another account"}). Every inbound agent will be turned away until the key or counterparty is corrected.`;
|
|
108
|
+
if (strictInit) {
|
|
109
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
110
|
+
}
|
|
111
|
+
console.error(message);
|
|
112
|
+
}
|
|
82
113
|
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
83
114
|
console.warn(
|
|
84
115
|
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
@@ -223,11 +254,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
223
254
|
const isMisconfig = source === "merchant_misconfig";
|
|
224
255
|
const urls = options.urls;
|
|
225
256
|
const guidance = isMisconfig ? {
|
|
226
|
-
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or
|
|
257
|
+
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, rotated, or belongs to another account). Your identity and the AstraSync platform are fine \u2014 contact the site operator. Retrying will not help.",
|
|
227
258
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
228
259
|
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
229
260
|
steps: [
|
|
230
|
-
"Report the failure to the site operator \u2014 their AstraSync API key needs
|
|
261
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs replacing",
|
|
231
262
|
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
232
263
|
]
|
|
233
264
|
} : isApiError ? {
|
|
@@ -288,11 +319,44 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
288
319
|
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
289
320
|
// deterministic and intentionally NOT marked retryable.
|
|
290
321
|
...isApiError && { retryable: true },
|
|
322
|
+
...options.httpStatus !== void 0 && { httpStatus: options.httpStatus },
|
|
323
|
+
...options.retryAfterMs !== void 0 && { retryAfterMs: options.retryAfterMs },
|
|
291
324
|
correlationId: options.correlationId,
|
|
292
325
|
attemptId: options.attemptId,
|
|
293
326
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
294
327
|
};
|
|
295
328
|
}
|
|
329
|
+
async function readJsonSafe(response) {
|
|
330
|
+
try {
|
|
331
|
+
const parsed = await response.json();
|
|
332
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
333
|
+
} catch {
|
|
334
|
+
return {};
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
function rejectedIdentityGuidance(failures) {
|
|
338
|
+
const f = failures?.find((x) => REJECTED_IDENTITY_DIMENSIONS.has(x.dimension));
|
|
339
|
+
if (!f) return void 0;
|
|
340
|
+
if (f.dimension === "agent.lookup") {
|
|
341
|
+
return `The presented agent identifier is not registered with AstraSync. ${UNKNOWN_AGENT_GUIDANCE}`;
|
|
342
|
+
}
|
|
343
|
+
return f.guidance ? `${f.message} ${f.guidance}` : f.message;
|
|
344
|
+
}
|
|
345
|
+
var MAX_RETRY_AFTER_MS = 15 * 60 * 1e3;
|
|
346
|
+
function parseRetryAfterMs(response) {
|
|
347
|
+
const raw = response.headers?.get?.("retry-after");
|
|
348
|
+
if (!raw) return void 0;
|
|
349
|
+
const trimmed = raw.trim();
|
|
350
|
+
let ms;
|
|
351
|
+
if (/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
352
|
+
ms = Number(trimmed) * 1e3;
|
|
353
|
+
} else {
|
|
354
|
+
const at = Date.parse(trimmed);
|
|
355
|
+
if (Number.isNaN(at)) return void 0;
|
|
356
|
+
ms = at - Date.now();
|
|
357
|
+
}
|
|
358
|
+
return Math.min(MAX_RETRY_AFTER_MS, Math.max(0, Math.round(ms)));
|
|
359
|
+
}
|
|
296
360
|
async function callVerifyAccessAPI(config, request) {
|
|
297
361
|
const { credentials, ...requestData } = request;
|
|
298
362
|
const body = {
|
|
@@ -349,7 +413,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
349
413
|
body: JSON.stringify(body),
|
|
350
414
|
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
351
415
|
});
|
|
352
|
-
const data = await response
|
|
416
|
+
const data = await readJsonSafe(response);
|
|
417
|
+
const retryAfterMs = parseRetryAfterMs(response);
|
|
353
418
|
if (response.status === 410) {
|
|
354
419
|
return {
|
|
355
420
|
success: true,
|
|
@@ -387,13 +452,31 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
387
452
|
}
|
|
388
453
|
};
|
|
389
454
|
}
|
|
455
|
+
if (response.status === 404 && credentials.astraId && (data?.error === "AGENT_NOT_FOUND" || typeof data?.message === "string" && /agent/i.test(data.message))) {
|
|
456
|
+
return {
|
|
457
|
+
success: true,
|
|
458
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
459
|
+
access: {
|
|
460
|
+
allowed: false,
|
|
461
|
+
reason: "unknown_agent",
|
|
462
|
+
failures: [
|
|
463
|
+
{
|
|
464
|
+
dimension: "identity.unknown_agent",
|
|
465
|
+
message: "The presented agent identifier is not registered with AstraSync.",
|
|
466
|
+
guidance: UNKNOWN_AGENT_GUIDANCE
|
|
467
|
+
}
|
|
468
|
+
]
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
}
|
|
390
472
|
if (!response.ok) {
|
|
391
|
-
|
|
473
|
+
const keyMismatch = response.status === 403 && data?.error === "COUNTERPARTY_KEY_MISMATCH";
|
|
474
|
+
if (response.status === 401 || keyMismatch) {
|
|
392
475
|
return {
|
|
393
476
|
success: false,
|
|
394
477
|
error: data.message || data.error || "Integration API key rejected",
|
|
395
478
|
misconfig: true,
|
|
396
|
-
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
479
|
+
misconfigCode: keyMismatch ? "counterparty_key_mismatch" : typeof data?.code === "string" ? data.code : void 0,
|
|
397
480
|
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
398
481
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
399
482
|
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
@@ -401,9 +484,11 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
401
484
|
}
|
|
402
485
|
return {
|
|
403
486
|
success: false,
|
|
404
|
-
error: data.message || data.error || `API returned ${response.status}`,
|
|
487
|
+
error: typeof data?.message === "string" && data.message || typeof data?.error === "string" && data.error || `API returned ${response.status}`,
|
|
405
488
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
406
|
-
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
489
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
490
|
+
httpStatus: response.status,
|
|
491
|
+
...retryAfterMs !== void 0 && { retryAfterMs }
|
|
407
492
|
};
|
|
408
493
|
}
|
|
409
494
|
return data;
|
|
@@ -424,14 +509,22 @@ async function verify(config, request, options) {
|
|
|
424
509
|
mergedConfig.apiBaseUrl,
|
|
425
510
|
mergedConfig.debug,
|
|
426
511
|
true,
|
|
427
|
-
mergedConfig.apiKey
|
|
512
|
+
mergedConfig.apiKey,
|
|
513
|
+
{
|
|
514
|
+
id: mergedConfig.counterpartyId,
|
|
515
|
+
url: mergedConfig.counterpartyUrl ?? request.counterpartyUrl
|
|
516
|
+
}
|
|
428
517
|
);
|
|
429
518
|
} else {
|
|
430
519
|
void performInitCheck(
|
|
431
520
|
mergedConfig.apiBaseUrl,
|
|
432
521
|
mergedConfig.debug,
|
|
433
522
|
false,
|
|
434
|
-
mergedConfig.apiKey
|
|
523
|
+
mergedConfig.apiKey,
|
|
524
|
+
{
|
|
525
|
+
id: mergedConfig.counterpartyId,
|
|
526
|
+
url: mergedConfig.counterpartyUrl ?? request.counterpartyUrl
|
|
527
|
+
}
|
|
435
528
|
);
|
|
436
529
|
}
|
|
437
530
|
}
|
|
@@ -475,12 +568,14 @@ async function verify(config, request, options) {
|
|
|
475
568
|
correlationId: apiResponse.correlationId,
|
|
476
569
|
attemptId: apiResponse.attemptId,
|
|
477
570
|
remediation: apiResponse.remediation,
|
|
571
|
+
httpStatus: apiResponse.httpStatus,
|
|
572
|
+
retryAfterMs: apiResponse.retryAfterMs,
|
|
478
573
|
urls
|
|
479
574
|
});
|
|
480
575
|
}
|
|
481
576
|
if (!apiResponse.access?.allowed) {
|
|
482
577
|
const aggregatedFailures = apiResponse.access?.failures;
|
|
483
|
-
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true;
|
|
578
|
+
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true && !aggregatedFailures?.some((f) => REJECTED_IDENTITY_DIMENSIONS.has(f.dimension));
|
|
484
579
|
const result2 = {
|
|
485
580
|
identityVerified: idVerifiedFromBackend,
|
|
486
581
|
policyAllowed: false,
|
|
@@ -492,7 +587,10 @@ async function verify(config, request, options) {
|
|
|
492
587
|
requiresStepUp: apiResponse.access?.requiresStepUp,
|
|
493
588
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
494
589
|
guidance: {
|
|
495
|
-
|
|
590
|
+
// 5.12.0: a presented-but-rejected id (malformed / unknown) carries
|
|
591
|
+
// actionable registration guidance on its failure — surface it
|
|
592
|
+
// instead of the bare machine reason ('unknown_agent').
|
|
593
|
+
message: rejectedIdentityGuidance(aggregatedFailures) ?? (apiResponse.access?.reason || "Access denied by PDLSS policy"),
|
|
496
594
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
497
595
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
498
596
|
// 5.1.0: anonymous callers land on this branch — steer MCP-hosted
|
|
@@ -592,7 +690,7 @@ async function verify(config, request, options) {
|
|
|
592
690
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
593
691
|
documentationUrl: urls?.documentationUrl ?? ""
|
|
594
692
|
};
|
|
595
|
-
} else if (result.recommendation === "step_up_required") {
|
|
693
|
+
} else if (result.recommendation === "step_up_required" && result.identityVerified) {
|
|
596
694
|
result.requiresStepUp = true;
|
|
597
695
|
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
|
|
598
696
|
}
|
|
@@ -615,7 +713,7 @@ async function recordDecision(config, sessionId, decision, reason) {
|
|
|
615
713
|
}).catch(() => {
|
|
616
714
|
});
|
|
617
715
|
}
|
|
618
|
-
async function reportAttempt(config, report) {
|
|
716
|
+
async function reportAttempt(config, report, options = {}) {
|
|
619
717
|
const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
|
|
620
718
|
const headers = { "Content-Type": "application/json" };
|
|
621
719
|
if (config.apiKey) {
|
|
@@ -626,13 +724,38 @@ async function reportAttempt(config, report) {
|
|
|
626
724
|
...report,
|
|
627
725
|
...!report.counterpartyId && config.counterpartyId && { counterpartyId: config.counterpartyId }
|
|
628
726
|
};
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
727
|
+
const url = `${apiBaseUrl}/agents/verify-access/attempt-report`;
|
|
728
|
+
const init = { method: "POST", headers, body: JSON.stringify(body) };
|
|
729
|
+
const fail = (failure) => {
|
|
730
|
+
try {
|
|
731
|
+
options.onFailure?.(failure);
|
|
732
|
+
} catch {
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
let response;
|
|
736
|
+
try {
|
|
737
|
+
response = await sdkFetch(url, init);
|
|
738
|
+
} catch (err) {
|
|
739
|
+
fail({ error: err instanceof Error ? err.message : String(err), retried: false });
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
if (response.ok) return;
|
|
743
|
+
if (response.status !== 429 && response.status < 500) {
|
|
744
|
+
fail({ status: response.status, retried: false });
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
const delayMs = Math.min(ATTEMPT_REPORT_MAX_RETRY_DELAY_MS, parseRetryAfterMs(response) ?? 500);
|
|
748
|
+
const timer = setTimeout(() => {
|
|
749
|
+
sdkFetch(url, init).then((retry) => {
|
|
750
|
+
if (!retry.ok) fail({ status: retry.status, retried: true });
|
|
751
|
+
}).catch((err) => {
|
|
752
|
+
fail({ error: err instanceof Error ? err.message : String(err), retried: true });
|
|
753
|
+
});
|
|
754
|
+
}, delayMs);
|
|
755
|
+
timer.unref?.();
|
|
635
756
|
}
|
|
757
|
+
var ATTEMPT_REPORT_MAX_RETRY_DELAY_MS = 2e3;
|
|
758
|
+
var refusedPolicyReads = /* @__PURE__ */ new Set();
|
|
636
759
|
async function fetchRoutes(config, counterpartyId) {
|
|
637
760
|
if (!counterpartyId) return null;
|
|
638
761
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -645,7 +768,15 @@ async function fetchRoutes(config, counterpartyId) {
|
|
|
645
768
|
`${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/routes`,
|
|
646
769
|
{ method: "GET", headers }
|
|
647
770
|
);
|
|
648
|
-
if (!response.ok)
|
|
771
|
+
if (!response.ok) {
|
|
772
|
+
if ((response.status === 401 || response.status === 403 || response.status === 404) && !refusedPolicyReads.has(counterpartyId)) {
|
|
773
|
+
refusedPolicyReads.add(counterpartyId);
|
|
774
|
+
console.error(
|
|
775
|
+
`[VerificationGateway] the configured API key cannot read the route policy for ${counterpartyId} (HTTP ${response.status}). The key belongs to an account that does not own this endpoint, or the counterpartyId is wrong. The gateway is in PASS-THROUGH mode: no agent is being verified.`
|
|
776
|
+
);
|
|
777
|
+
}
|
|
778
|
+
return null;
|
|
779
|
+
}
|
|
649
780
|
const body = await response.json();
|
|
650
781
|
return body.data?.routes ?? [];
|
|
651
782
|
} catch {
|
|
@@ -677,7 +808,10 @@ async function reportUnregisteredAttempt(config, data) {
|
|
|
677
808
|
};
|
|
678
809
|
await sdkFetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
|
|
679
810
|
method: "POST",
|
|
680
|
-
headers: {
|
|
811
|
+
headers: {
|
|
812
|
+
"Content-Type": "application/json",
|
|
813
|
+
...config.apiKey && { Authorization: `Bearer ${config.apiKey}` }
|
|
814
|
+
},
|
|
681
815
|
body: JSON.stringify(body)
|
|
682
816
|
}).catch(() => {
|
|
683
817
|
});
|
|
@@ -699,7 +833,11 @@ async function quickVerify(config, credentials) {
|
|
|
699
833
|
return {
|
|
700
834
|
identityVerified: result.identityVerified,
|
|
701
835
|
policyAllowed: result.policyAllowed,
|
|
702
|
-
reason: result.denialReasons?.[0]
|
|
836
|
+
reason: result.denialReasons?.[0],
|
|
837
|
+
...isVerificationUnavailable(result) && {
|
|
838
|
+
unavailable: true,
|
|
839
|
+
retryAfterMs: unavailableRetryAfterSeconds(result) * 1e3
|
|
840
|
+
}
|
|
703
841
|
};
|
|
704
842
|
}
|
|
705
843
|
export {
|
|
@@ -708,6 +846,7 @@ export {
|
|
|
708
846
|
extractCredentials,
|
|
709
847
|
fetchRoutes,
|
|
710
848
|
hasCredentials,
|
|
849
|
+
parseRetryAfterMs,
|
|
711
850
|
quickVerify,
|
|
712
851
|
recordDecision,
|
|
713
852
|
reportAttempt,
|