@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
|
@@ -458,6 +458,18 @@ interface VerificationResult {
|
|
|
458
458
|
* on misconfig (deterministic — retrying will not help) and on real denials.
|
|
459
459
|
*/
|
|
460
460
|
retryable?: boolean;
|
|
461
|
+
/**
|
|
462
|
+
* 5.12.0: HTTP status the verify-access backend answered with on a
|
|
463
|
+
* non-2xx (e.g. 429, 503). Lets adapters and integrators tell a platform
|
|
464
|
+
* rate limit apart from an outage. Absent on network errors / timeouts.
|
|
465
|
+
*/
|
|
466
|
+
httpStatus?: number;
|
|
467
|
+
/**
|
|
468
|
+
* 5.12.0: the backend's `Retry-After`, in milliseconds, when it sent one
|
|
469
|
+
* (429 / 503). Adapters relay it on their own 503 so callers back off for
|
|
470
|
+
* as long as the platform asked.
|
|
471
|
+
*/
|
|
472
|
+
retryAfterMs?: number;
|
|
461
473
|
/** Whether step-up authentication is required */
|
|
462
474
|
requiresStepUp?: boolean;
|
|
463
475
|
/** Whether approval is required */
|
|
@@ -458,6 +458,18 @@ interface VerificationResult {
|
|
|
458
458
|
* on misconfig (deterministic — retrying will not help) and on real denials.
|
|
459
459
|
*/
|
|
460
460
|
retryable?: boolean;
|
|
461
|
+
/**
|
|
462
|
+
* 5.12.0: HTTP status the verify-access backend answered with on a
|
|
463
|
+
* non-2xx (e.g. 429, 503). Lets adapters and integrators tell a platform
|
|
464
|
+
* rate limit apart from an outage. Absent on network errors / timeouts.
|
|
465
|
+
*/
|
|
466
|
+
httpStatus?: number;
|
|
467
|
+
/**
|
|
468
|
+
* 5.12.0: the backend's `Retry-After`, in milliseconds, when it sent one
|
|
469
|
+
* (429 / 503). Adapters relay it on their own 503 so callers back off for
|
|
470
|
+
* as long as the platform asked.
|
|
471
|
+
*/
|
|
472
|
+
retryAfterMs?: number;
|
|
461
473
|
/** Whether step-up authentication is required */
|
|
462
474
|
requiresStepUp?: boolean;
|
|
463
475
|
/** Whether approval is required */
|
|
@@ -400,6 +400,18 @@ interface VerificationResult {
|
|
|
400
400
|
* on misconfig (deterministic — retrying will not help) and on real denials.
|
|
401
401
|
*/
|
|
402
402
|
retryable?: boolean;
|
|
403
|
+
/**
|
|
404
|
+
* 5.12.0: HTTP status the verify-access backend answered with on a
|
|
405
|
+
* non-2xx (e.g. 429, 503). Lets adapters and integrators tell a platform
|
|
406
|
+
* rate limit apart from an outage. Absent on network errors / timeouts.
|
|
407
|
+
*/
|
|
408
|
+
httpStatus?: number;
|
|
409
|
+
/**
|
|
410
|
+
* 5.12.0: the backend's `Retry-After`, in milliseconds, when it sent one
|
|
411
|
+
* (429 / 503). Adapters relay it on their own 503 so callers back off for
|
|
412
|
+
* as long as the platform asked.
|
|
413
|
+
*/
|
|
414
|
+
retryAfterMs?: number;
|
|
403
415
|
/** Whether step-up authentication is required */
|
|
404
416
|
requiresStepUp?: boolean;
|
|
405
417
|
/** Whether approval is required */
|
|
@@ -764,6 +776,12 @@ interface AttemptReport {
|
|
|
764
776
|
agentId?: string;
|
|
765
777
|
considerationSet?: ConsiderationSet;
|
|
766
778
|
outcome?: AttemptOutcome;
|
|
779
|
+
/**
|
|
780
|
+
* Where a catalog view was answered from: `bridge_cache` (the AstraSync
|
|
781
|
+
* bridge's anonymous cache — no load on the merchant's site) or `merchant`
|
|
782
|
+
* (fetched fresh). Attribution only.
|
|
783
|
+
*/
|
|
784
|
+
servedFrom?: 'bridge_cache' | 'merchant';
|
|
767
785
|
}
|
|
768
786
|
/**
|
|
769
787
|
* Raw commerce-protocol artifacts as verify-access accepts them (backend
|
|
@@ -400,6 +400,18 @@ interface VerificationResult {
|
|
|
400
400
|
* on misconfig (deterministic — retrying will not help) and on real denials.
|
|
401
401
|
*/
|
|
402
402
|
retryable?: boolean;
|
|
403
|
+
/**
|
|
404
|
+
* 5.12.0: HTTP status the verify-access backend answered with on a
|
|
405
|
+
* non-2xx (e.g. 429, 503). Lets adapters and integrators tell a platform
|
|
406
|
+
* rate limit apart from an outage. Absent on network errors / timeouts.
|
|
407
|
+
*/
|
|
408
|
+
httpStatus?: number;
|
|
409
|
+
/**
|
|
410
|
+
* 5.12.0: the backend's `Retry-After`, in milliseconds, when it sent one
|
|
411
|
+
* (429 / 503). Adapters relay it on their own 503 so callers back off for
|
|
412
|
+
* as long as the platform asked.
|
|
413
|
+
*/
|
|
414
|
+
retryAfterMs?: number;
|
|
403
415
|
/** Whether step-up authentication is required */
|
|
404
416
|
requiresStepUp?: boolean;
|
|
405
417
|
/** Whether approval is required */
|
|
@@ -764,6 +776,12 @@ interface AttemptReport {
|
|
|
764
776
|
agentId?: string;
|
|
765
777
|
considerationSet?: ConsiderationSet;
|
|
766
778
|
outcome?: AttemptOutcome;
|
|
779
|
+
/**
|
|
780
|
+
* Where a catalog view was answered from: `bridge_cache` (the AstraSync
|
|
781
|
+
* bridge's anonymous cache — no load on the merchant's site) or `merchant`
|
|
782
|
+
* (fetched fresh). Attribution only.
|
|
783
|
+
*/
|
|
784
|
+
servedFrom?: 'bridge_cache' | 'merchant';
|
|
767
785
|
}
|
|
768
786
|
/**
|
|
769
787
|
* Raw commerce-protocol artifacts as verify-access accepts them (backend
|
package/dist/ui/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { V as VerificationInterstitialProps, d as VerificationResult, A as AgentCredentials, b as GuidanceInfo, T as TrustLevel } from '../types-
|
|
1
|
+
import { V as VerificationInterstitialProps, d as VerificationResult, A as AgentCredentials, b as GuidanceInfo, T as TrustLevel } from '../types-BCkwBA84.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* AstraSync Verification Interstitial Component
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { V as VerificationInterstitialProps, d as VerificationResult, A as AgentCredentials, b as GuidanceInfo, T as TrustLevel } from '../types-
|
|
1
|
+
import { V as VerificationInterstitialProps, d as VerificationResult, A as AgentCredentials, b as GuidanceInfo, T as TrustLevel } from '../types-BCkwBA84.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* AstraSync Verification Interstitial Component
|
package/dist/verify.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AgentCredentials, G as GatewayConfig, a as AttemptReport, V as VerificationRequest, c as VerificationResult } from './types-
|
|
1
|
+
import { A as AgentCredentials, G as GatewayConfig, a as AttemptReport, V as VerificationRequest, c as VerificationResult } from './types-DlshIIR-.mjs';
|
|
2
2
|
import { ObservedMetadata } from './metadata-capture.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -22,6 +22,15 @@ declare function extractCredentials(headers: Record<string, string | string[] |
|
|
|
22
22
|
* Check if credentials are present
|
|
23
23
|
*/
|
|
24
24
|
declare function hasCredentials(credentials: AgentCredentials): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* 5.12.0: `Retry-After` (delta-seconds or HTTP-date) → milliseconds, or
|
|
27
|
+
* undefined when absent/unparseable. Clamped to [0, 15 min].
|
|
28
|
+
*/
|
|
29
|
+
declare function parseRetryAfterMs(response: {
|
|
30
|
+
headers?: {
|
|
31
|
+
get?(name: string): string | null;
|
|
32
|
+
};
|
|
33
|
+
}): number | undefined;
|
|
25
34
|
/**
|
|
26
35
|
* Options for a single verify() call (as opposed to GatewayConfig, which is
|
|
27
36
|
* per-gateway). Mirrors the Java SDK's `verify(request, bypassCache)`.
|
|
@@ -52,19 +61,24 @@ declare function recordDecision(config: GatewayConfig, sessionId: string, decisi
|
|
|
52
61
|
* Authenticated with the same credentials as verify(); the backend responds
|
|
53
62
|
* 202 and folds the data into the attempt chain keyed by `attemptId`.
|
|
54
63
|
*
|
|
55
|
-
* Fire-and-forget —
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Fetch the per-route policy for an endpoint from the AstraSync backend.
|
|
60
|
-
* v2.9.7 moved policy authority into the dashboard — the SDK no longer
|
|
61
|
-
* accepts `routes` from merchant-side source code, it fetches them from
|
|
62
|
-
* here on init (and refreshes periodically).
|
|
63
|
-
*
|
|
64
|
-
* Returns `null` when the request fails for any reason — the caller decides
|
|
65
|
-
* how to fall back (the middleware allows-all when no policy is loaded so
|
|
66
|
-
* a misconfigured init doesn't take down the merchant's API).
|
|
64
|
+
* Fire-and-forget — never throws. 5.12.0: a 429/5xx is retried once
|
|
65
|
+
* (Retry-After honoured, capped at 2s) off the caller's path; a lost report
|
|
66
|
+
* is surfaced via `options.onFailure`.
|
|
67
67
|
*/
|
|
68
|
+
declare function reportAttempt(config: GatewayConfig, report: AttemptReport, options?: ReportAttemptOptions): Promise<void>;
|
|
69
|
+
/** 5.12.0: options for {@link reportAttempt}. */
|
|
70
|
+
interface ReportAttemptOptions {
|
|
71
|
+
/**
|
|
72
|
+
* Called once when the report is finally lost (non-retryable status,
|
|
73
|
+
* network error, or the single retry failed). For counters/telemetry;
|
|
74
|
+
* exceptions it throws are swallowed.
|
|
75
|
+
*/
|
|
76
|
+
onFailure?: (failure: {
|
|
77
|
+
status?: number;
|
|
78
|
+
error?: string;
|
|
79
|
+
retried: boolean;
|
|
80
|
+
}) => void;
|
|
81
|
+
}
|
|
68
82
|
declare function fetchRoutes(config: GatewayConfig, counterpartyId: string): Promise<RouteAccessConfigShape[] | null>;
|
|
69
83
|
/**
|
|
70
84
|
* Minimal shape of an EndpointRoute as the SDK consumes it. Mirrors the
|
|
@@ -171,6 +185,13 @@ declare function quickVerify(config: GatewayConfig, credentials: AgentCredential
|
|
|
171
185
|
identityVerified: boolean;
|
|
172
186
|
policyAllowed: boolean;
|
|
173
187
|
reason?: string;
|
|
188
|
+
/**
|
|
189
|
+
* 5.12.0: verification infrastructure was unavailable (timeout / 5xx /
|
|
190
|
+
* the platform's 429) — NOT a denial. Callers should fail open on reads
|
|
191
|
+
* or answer 503 + Retry-After (`retryAfterMs`, else 30s), never 401.
|
|
192
|
+
*/
|
|
193
|
+
unavailable?: true;
|
|
194
|
+
retryAfterMs?: number;
|
|
174
195
|
}>;
|
|
175
196
|
|
|
176
|
-
export { type RouteAccessConfigShape, type VerifyOptions, _resetInitCheck, clearCache, extractCredentials, fetchRoutes, hasCredentials, quickVerify, recordDecision, reportAttempt, reportCounterpartyPreCheckFailure, reportUnregisteredAttempt, verify, verifyAndRecord };
|
|
197
|
+
export { type ReportAttemptOptions, type RouteAccessConfigShape, type VerifyOptions, _resetInitCheck, clearCache, extractCredentials, fetchRoutes, hasCredentials, parseRetryAfterMs, quickVerify, recordDecision, reportAttempt, reportCounterpartyPreCheckFailure, reportUnregisteredAttempt, verify, verifyAndRecord };
|
package/dist/verify.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AgentCredentials, G as GatewayConfig, a as AttemptReport, V as VerificationRequest, c as VerificationResult } from './types-
|
|
1
|
+
import { A as AgentCredentials, G as GatewayConfig, a as AttemptReport, V as VerificationRequest, c as VerificationResult } from './types-C_b4QTyO.js';
|
|
2
2
|
import { ObservedMetadata } from './metadata-capture.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -22,6 +22,15 @@ declare function extractCredentials(headers: Record<string, string | string[] |
|
|
|
22
22
|
* Check if credentials are present
|
|
23
23
|
*/
|
|
24
24
|
declare function hasCredentials(credentials: AgentCredentials): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* 5.12.0: `Retry-After` (delta-seconds or HTTP-date) → milliseconds, or
|
|
27
|
+
* undefined when absent/unparseable. Clamped to [0, 15 min].
|
|
28
|
+
*/
|
|
29
|
+
declare function parseRetryAfterMs(response: {
|
|
30
|
+
headers?: {
|
|
31
|
+
get?(name: string): string | null;
|
|
32
|
+
};
|
|
33
|
+
}): number | undefined;
|
|
25
34
|
/**
|
|
26
35
|
* Options for a single verify() call (as opposed to GatewayConfig, which is
|
|
27
36
|
* per-gateway). Mirrors the Java SDK's `verify(request, bypassCache)`.
|
|
@@ -52,19 +61,24 @@ declare function recordDecision(config: GatewayConfig, sessionId: string, decisi
|
|
|
52
61
|
* Authenticated with the same credentials as verify(); the backend responds
|
|
53
62
|
* 202 and folds the data into the attempt chain keyed by `attemptId`.
|
|
54
63
|
*
|
|
55
|
-
* Fire-and-forget —
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Fetch the per-route policy for an endpoint from the AstraSync backend.
|
|
60
|
-
* v2.9.7 moved policy authority into the dashboard — the SDK no longer
|
|
61
|
-
* accepts `routes` from merchant-side source code, it fetches them from
|
|
62
|
-
* here on init (and refreshes periodically).
|
|
63
|
-
*
|
|
64
|
-
* Returns `null` when the request fails for any reason — the caller decides
|
|
65
|
-
* how to fall back (the middleware allows-all when no policy is loaded so
|
|
66
|
-
* a misconfigured init doesn't take down the merchant's API).
|
|
64
|
+
* Fire-and-forget — never throws. 5.12.0: a 429/5xx is retried once
|
|
65
|
+
* (Retry-After honoured, capped at 2s) off the caller's path; a lost report
|
|
66
|
+
* is surfaced via `options.onFailure`.
|
|
67
67
|
*/
|
|
68
|
+
declare function reportAttempt(config: GatewayConfig, report: AttemptReport, options?: ReportAttemptOptions): Promise<void>;
|
|
69
|
+
/** 5.12.0: options for {@link reportAttempt}. */
|
|
70
|
+
interface ReportAttemptOptions {
|
|
71
|
+
/**
|
|
72
|
+
* Called once when the report is finally lost (non-retryable status,
|
|
73
|
+
* network error, or the single retry failed). For counters/telemetry;
|
|
74
|
+
* exceptions it throws are swallowed.
|
|
75
|
+
*/
|
|
76
|
+
onFailure?: (failure: {
|
|
77
|
+
status?: number;
|
|
78
|
+
error?: string;
|
|
79
|
+
retried: boolean;
|
|
80
|
+
}) => void;
|
|
81
|
+
}
|
|
68
82
|
declare function fetchRoutes(config: GatewayConfig, counterpartyId: string): Promise<RouteAccessConfigShape[] | null>;
|
|
69
83
|
/**
|
|
70
84
|
* Minimal shape of an EndpointRoute as the SDK consumes it. Mirrors the
|
|
@@ -171,6 +185,13 @@ declare function quickVerify(config: GatewayConfig, credentials: AgentCredential
|
|
|
171
185
|
identityVerified: boolean;
|
|
172
186
|
policyAllowed: boolean;
|
|
173
187
|
reason?: string;
|
|
188
|
+
/**
|
|
189
|
+
* 5.12.0: verification infrastructure was unavailable (timeout / 5xx /
|
|
190
|
+
* the platform's 429) — NOT a denial. Callers should fail open on reads
|
|
191
|
+
* or answer 503 + Retry-After (`retryAfterMs`, else 30s), never 401.
|
|
192
|
+
*/
|
|
193
|
+
unavailable?: true;
|
|
194
|
+
retryAfterMs?: number;
|
|
174
195
|
}>;
|
|
175
196
|
|
|
176
|
-
export { type RouteAccessConfigShape, type VerifyOptions, _resetInitCheck, clearCache, extractCredentials, fetchRoutes, hasCredentials, quickVerify, recordDecision, reportAttempt, reportCounterpartyPreCheckFailure, reportUnregisteredAttempt, verify, verifyAndRecord };
|
|
197
|
+
export { type ReportAttemptOptions, type RouteAccessConfigShape, type VerifyOptions, _resetInitCheck, clearCache, extractCredentials, fetchRoutes, hasCredentials, parseRetryAfterMs, quickVerify, recordDecision, reportAttempt, reportCounterpartyPreCheckFailure, reportUnregisteredAttempt, verify, verifyAndRecord };
|
package/dist/verify.js
CHANGED
|
@@ -25,6 +25,7 @@ __export(verify_exports, {
|
|
|
25
25
|
extractCredentials: () => extractCredentials,
|
|
26
26
|
fetchRoutes: () => fetchRoutes,
|
|
27
27
|
hasCredentials: () => hasCredentials,
|
|
28
|
+
parseRetryAfterMs: () => parseRetryAfterMs,
|
|
28
29
|
quickVerify: () => quickVerify,
|
|
29
30
|
recordDecision: () => recordDecision,
|
|
30
31
|
reportAttempt: () => reportAttempt,
|
|
@@ -36,7 +37,7 @@ __export(verify_exports, {
|
|
|
36
37
|
module.exports = __toCommonJS(verify_exports);
|
|
37
38
|
|
|
38
39
|
// src/version.ts
|
|
39
|
-
var SDK_VERSION = "5.
|
|
40
|
+
var SDK_VERSION = "5.13.0";
|
|
40
41
|
|
|
41
42
|
// src/http.ts
|
|
42
43
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -71,6 +72,29 @@ function getCachedWellKnownUrls(apiBaseUrl) {
|
|
|
71
72
|
return cache.get(apiBaseUrl)?.data;
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
// src/failure-posture.ts
|
|
76
|
+
var DEFAULT_UNAVAILABLE_RETRY_AFTER_S = 30;
|
|
77
|
+
var REJECTED_IDENTITY_DIMENSIONS = /* @__PURE__ */ new Set([
|
|
78
|
+
"identity.invalid_agent_id",
|
|
79
|
+
"identity.unknown_agent",
|
|
80
|
+
"agent.lookup"
|
|
81
|
+
]);
|
|
82
|
+
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.";
|
|
83
|
+
var UNAVAILABLE_DIMENSIONS = /* @__PURE__ */ new Set([
|
|
84
|
+
"verify_access.api_error",
|
|
85
|
+
"middleware.internal_error"
|
|
86
|
+
]);
|
|
87
|
+
function isVerificationUnavailable(result) {
|
|
88
|
+
if (result.misconfigured) return false;
|
|
89
|
+
return (result.failures ?? []).some((f) => UNAVAILABLE_DIMENSIONS.has(f.dimension));
|
|
90
|
+
}
|
|
91
|
+
function unavailableRetryAfterSeconds(result) {
|
|
92
|
+
if (typeof result.retryAfterMs === "number" && Number.isFinite(result.retryAfterMs)) {
|
|
93
|
+
return Math.max(1, Math.ceil(result.retryAfterMs / 1e3));
|
|
94
|
+
}
|
|
95
|
+
return DEFAULT_UNAVAILABLE_RETRY_AFTER_S;
|
|
96
|
+
}
|
|
97
|
+
|
|
74
98
|
// src/verify.ts
|
|
75
99
|
var DEFAULT_CONFIG = {
|
|
76
100
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
@@ -86,7 +110,7 @@ function _resetInitCheck() {
|
|
|
86
110
|
initCheckPerformed = false;
|
|
87
111
|
}
|
|
88
112
|
var deprecationWarningShown = false;
|
|
89
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
113
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey, counterparty) {
|
|
90
114
|
initCheckPerformed = true;
|
|
91
115
|
try {
|
|
92
116
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -104,7 +128,8 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
104
128
|
);
|
|
105
129
|
}
|
|
106
130
|
if (apiKey) {
|
|
107
|
-
const
|
|
131
|
+
const q = counterparty?.id ? `?counterpartyId=${encodeURIComponent(counterparty.id)}` : counterparty?.url ? `?counterpartyUrl=${encodeURIComponent(counterparty.url)}` : "";
|
|
132
|
+
const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check${q}`, {
|
|
108
133
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
109
134
|
});
|
|
110
135
|
if (selfCheck.status === 401) {
|
|
@@ -116,6 +141,13 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
116
141
|
console.error(message);
|
|
117
142
|
} else if (selfCheck.ok) {
|
|
118
143
|
const body = await selfCheck.json().catch(() => ({}));
|
|
144
|
+
if (body.counterparty && body.counterparty.canVerify === false) {
|
|
145
|
+
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.`;
|
|
146
|
+
if (strictInit) {
|
|
147
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
148
|
+
}
|
|
149
|
+
console.error(message);
|
|
150
|
+
}
|
|
119
151
|
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
120
152
|
console.warn(
|
|
121
153
|
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
@@ -260,11 +292,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
260
292
|
const isMisconfig = source === "merchant_misconfig";
|
|
261
293
|
const urls = options.urls;
|
|
262
294
|
const guidance = isMisconfig ? {
|
|
263
|
-
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or
|
|
295
|
+
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.",
|
|
264
296
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
265
297
|
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
266
298
|
steps: [
|
|
267
|
-
"Report the failure to the site operator \u2014 their AstraSync API key needs
|
|
299
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs replacing",
|
|
268
300
|
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
269
301
|
]
|
|
270
302
|
} : isApiError ? {
|
|
@@ -325,11 +357,44 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
325
357
|
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
326
358
|
// deterministic and intentionally NOT marked retryable.
|
|
327
359
|
...isApiError && { retryable: true },
|
|
360
|
+
...options.httpStatus !== void 0 && { httpStatus: options.httpStatus },
|
|
361
|
+
...options.retryAfterMs !== void 0 && { retryAfterMs: options.retryAfterMs },
|
|
328
362
|
correlationId: options.correlationId,
|
|
329
363
|
attemptId: options.attemptId,
|
|
330
364
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
331
365
|
};
|
|
332
366
|
}
|
|
367
|
+
async function readJsonSafe(response) {
|
|
368
|
+
try {
|
|
369
|
+
const parsed = await response.json();
|
|
370
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
371
|
+
} catch {
|
|
372
|
+
return {};
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
function rejectedIdentityGuidance(failures) {
|
|
376
|
+
const f = failures?.find((x) => REJECTED_IDENTITY_DIMENSIONS.has(x.dimension));
|
|
377
|
+
if (!f) return void 0;
|
|
378
|
+
if (f.dimension === "agent.lookup") {
|
|
379
|
+
return `The presented agent identifier is not registered with AstraSync. ${UNKNOWN_AGENT_GUIDANCE}`;
|
|
380
|
+
}
|
|
381
|
+
return f.guidance ? `${f.message} ${f.guidance}` : f.message;
|
|
382
|
+
}
|
|
383
|
+
var MAX_RETRY_AFTER_MS = 15 * 60 * 1e3;
|
|
384
|
+
function parseRetryAfterMs(response) {
|
|
385
|
+
const raw = response.headers?.get?.("retry-after");
|
|
386
|
+
if (!raw) return void 0;
|
|
387
|
+
const trimmed = raw.trim();
|
|
388
|
+
let ms;
|
|
389
|
+
if (/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
390
|
+
ms = Number(trimmed) * 1e3;
|
|
391
|
+
} else {
|
|
392
|
+
const at = Date.parse(trimmed);
|
|
393
|
+
if (Number.isNaN(at)) return void 0;
|
|
394
|
+
ms = at - Date.now();
|
|
395
|
+
}
|
|
396
|
+
return Math.min(MAX_RETRY_AFTER_MS, Math.max(0, Math.round(ms)));
|
|
397
|
+
}
|
|
333
398
|
async function callVerifyAccessAPI(config, request) {
|
|
334
399
|
const { credentials, ...requestData } = request;
|
|
335
400
|
const body = {
|
|
@@ -386,7 +451,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
386
451
|
body: JSON.stringify(body),
|
|
387
452
|
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
388
453
|
});
|
|
389
|
-
const data = await response
|
|
454
|
+
const data = await readJsonSafe(response);
|
|
455
|
+
const retryAfterMs = parseRetryAfterMs(response);
|
|
390
456
|
if (response.status === 410) {
|
|
391
457
|
return {
|
|
392
458
|
success: true,
|
|
@@ -424,13 +490,31 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
424
490
|
}
|
|
425
491
|
};
|
|
426
492
|
}
|
|
493
|
+
if (response.status === 404 && credentials.astraId && (data?.error === "AGENT_NOT_FOUND" || typeof data?.message === "string" && /agent/i.test(data.message))) {
|
|
494
|
+
return {
|
|
495
|
+
success: true,
|
|
496
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
497
|
+
access: {
|
|
498
|
+
allowed: false,
|
|
499
|
+
reason: "unknown_agent",
|
|
500
|
+
failures: [
|
|
501
|
+
{
|
|
502
|
+
dimension: "identity.unknown_agent",
|
|
503
|
+
message: "The presented agent identifier is not registered with AstraSync.",
|
|
504
|
+
guidance: UNKNOWN_AGENT_GUIDANCE
|
|
505
|
+
}
|
|
506
|
+
]
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
}
|
|
427
510
|
if (!response.ok) {
|
|
428
|
-
|
|
511
|
+
const keyMismatch = response.status === 403 && data?.error === "COUNTERPARTY_KEY_MISMATCH";
|
|
512
|
+
if (response.status === 401 || keyMismatch) {
|
|
429
513
|
return {
|
|
430
514
|
success: false,
|
|
431
515
|
error: data.message || data.error || "Integration API key rejected",
|
|
432
516
|
misconfig: true,
|
|
433
|
-
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
517
|
+
misconfigCode: keyMismatch ? "counterparty_key_mismatch" : typeof data?.code === "string" ? data.code : void 0,
|
|
434
518
|
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
435
519
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
436
520
|
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
@@ -438,9 +522,11 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
438
522
|
}
|
|
439
523
|
return {
|
|
440
524
|
success: false,
|
|
441
|
-
error: data.message || data.error || `API returned ${response.status}`,
|
|
525
|
+
error: typeof data?.message === "string" && data.message || typeof data?.error === "string" && data.error || `API returned ${response.status}`,
|
|
442
526
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
443
|
-
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
527
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
528
|
+
httpStatus: response.status,
|
|
529
|
+
...retryAfterMs !== void 0 && { retryAfterMs }
|
|
444
530
|
};
|
|
445
531
|
}
|
|
446
532
|
return data;
|
|
@@ -461,14 +547,22 @@ async function verify(config, request, options) {
|
|
|
461
547
|
mergedConfig.apiBaseUrl,
|
|
462
548
|
mergedConfig.debug,
|
|
463
549
|
true,
|
|
464
|
-
mergedConfig.apiKey
|
|
550
|
+
mergedConfig.apiKey,
|
|
551
|
+
{
|
|
552
|
+
id: mergedConfig.counterpartyId,
|
|
553
|
+
url: mergedConfig.counterpartyUrl ?? request.counterpartyUrl
|
|
554
|
+
}
|
|
465
555
|
);
|
|
466
556
|
} else {
|
|
467
557
|
void performInitCheck(
|
|
468
558
|
mergedConfig.apiBaseUrl,
|
|
469
559
|
mergedConfig.debug,
|
|
470
560
|
false,
|
|
471
|
-
mergedConfig.apiKey
|
|
561
|
+
mergedConfig.apiKey,
|
|
562
|
+
{
|
|
563
|
+
id: mergedConfig.counterpartyId,
|
|
564
|
+
url: mergedConfig.counterpartyUrl ?? request.counterpartyUrl
|
|
565
|
+
}
|
|
472
566
|
);
|
|
473
567
|
}
|
|
474
568
|
}
|
|
@@ -512,12 +606,14 @@ async function verify(config, request, options) {
|
|
|
512
606
|
correlationId: apiResponse.correlationId,
|
|
513
607
|
attemptId: apiResponse.attemptId,
|
|
514
608
|
remediation: apiResponse.remediation,
|
|
609
|
+
httpStatus: apiResponse.httpStatus,
|
|
610
|
+
retryAfterMs: apiResponse.retryAfterMs,
|
|
515
611
|
urls
|
|
516
612
|
});
|
|
517
613
|
}
|
|
518
614
|
if (!apiResponse.access?.allowed) {
|
|
519
615
|
const aggregatedFailures = apiResponse.access?.failures;
|
|
520
|
-
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true;
|
|
616
|
+
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true && !aggregatedFailures?.some((f) => REJECTED_IDENTITY_DIMENSIONS.has(f.dimension));
|
|
521
617
|
const result2 = {
|
|
522
618
|
identityVerified: idVerifiedFromBackend,
|
|
523
619
|
policyAllowed: false,
|
|
@@ -529,7 +625,10 @@ async function verify(config, request, options) {
|
|
|
529
625
|
requiresStepUp: apiResponse.access?.requiresStepUp,
|
|
530
626
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
531
627
|
guidance: {
|
|
532
|
-
|
|
628
|
+
// 5.12.0: a presented-but-rejected id (malformed / unknown) carries
|
|
629
|
+
// actionable registration guidance on its failure — surface it
|
|
630
|
+
// instead of the bare machine reason ('unknown_agent').
|
|
631
|
+
message: rejectedIdentityGuidance(aggregatedFailures) ?? (apiResponse.access?.reason || "Access denied by PDLSS policy"),
|
|
533
632
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
534
633
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
535
634
|
// 5.1.0: anonymous callers land on this branch — steer MCP-hosted
|
|
@@ -629,7 +728,7 @@ async function verify(config, request, options) {
|
|
|
629
728
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
630
729
|
documentationUrl: urls?.documentationUrl ?? ""
|
|
631
730
|
};
|
|
632
|
-
} else if (result.recommendation === "step_up_required") {
|
|
731
|
+
} else if (result.recommendation === "step_up_required" && result.identityVerified) {
|
|
633
732
|
result.requiresStepUp = true;
|
|
634
733
|
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
|
|
635
734
|
}
|
|
@@ -652,7 +751,7 @@ async function recordDecision(config, sessionId, decision, reason) {
|
|
|
652
751
|
}).catch(() => {
|
|
653
752
|
});
|
|
654
753
|
}
|
|
655
|
-
async function reportAttempt(config, report) {
|
|
754
|
+
async function reportAttempt(config, report, options = {}) {
|
|
656
755
|
const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
|
|
657
756
|
const headers = { "Content-Type": "application/json" };
|
|
658
757
|
if (config.apiKey) {
|
|
@@ -663,13 +762,38 @@ async function reportAttempt(config, report) {
|
|
|
663
762
|
...report,
|
|
664
763
|
...!report.counterpartyId && config.counterpartyId && { counterpartyId: config.counterpartyId }
|
|
665
764
|
};
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
765
|
+
const url = `${apiBaseUrl}/agents/verify-access/attempt-report`;
|
|
766
|
+
const init = { method: "POST", headers, body: JSON.stringify(body) };
|
|
767
|
+
const fail = (failure) => {
|
|
768
|
+
try {
|
|
769
|
+
options.onFailure?.(failure);
|
|
770
|
+
} catch {
|
|
771
|
+
}
|
|
772
|
+
};
|
|
773
|
+
let response;
|
|
774
|
+
try {
|
|
775
|
+
response = await sdkFetch(url, init);
|
|
776
|
+
} catch (err) {
|
|
777
|
+
fail({ error: err instanceof Error ? err.message : String(err), retried: false });
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
if (response.ok) return;
|
|
781
|
+
if (response.status !== 429 && response.status < 500) {
|
|
782
|
+
fail({ status: response.status, retried: false });
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
const delayMs = Math.min(ATTEMPT_REPORT_MAX_RETRY_DELAY_MS, parseRetryAfterMs(response) ?? 500);
|
|
786
|
+
const timer = setTimeout(() => {
|
|
787
|
+
sdkFetch(url, init).then((retry) => {
|
|
788
|
+
if (!retry.ok) fail({ status: retry.status, retried: true });
|
|
789
|
+
}).catch((err) => {
|
|
790
|
+
fail({ error: err instanceof Error ? err.message : String(err), retried: true });
|
|
791
|
+
});
|
|
792
|
+
}, delayMs);
|
|
793
|
+
timer.unref?.();
|
|
672
794
|
}
|
|
795
|
+
var ATTEMPT_REPORT_MAX_RETRY_DELAY_MS = 2e3;
|
|
796
|
+
var refusedPolicyReads = /* @__PURE__ */ new Set();
|
|
673
797
|
async function fetchRoutes(config, counterpartyId) {
|
|
674
798
|
if (!counterpartyId) return null;
|
|
675
799
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -682,7 +806,15 @@ async function fetchRoutes(config, counterpartyId) {
|
|
|
682
806
|
`${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/routes`,
|
|
683
807
|
{ method: "GET", headers }
|
|
684
808
|
);
|
|
685
|
-
if (!response.ok)
|
|
809
|
+
if (!response.ok) {
|
|
810
|
+
if ((response.status === 401 || response.status === 403 || response.status === 404) && !refusedPolicyReads.has(counterpartyId)) {
|
|
811
|
+
refusedPolicyReads.add(counterpartyId);
|
|
812
|
+
console.error(
|
|
813
|
+
`[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.`
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
return null;
|
|
817
|
+
}
|
|
686
818
|
const body = await response.json();
|
|
687
819
|
return body.data?.routes ?? [];
|
|
688
820
|
} catch {
|
|
@@ -714,7 +846,10 @@ async function reportUnregisteredAttempt(config, data) {
|
|
|
714
846
|
};
|
|
715
847
|
await sdkFetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
|
|
716
848
|
method: "POST",
|
|
717
|
-
headers: {
|
|
849
|
+
headers: {
|
|
850
|
+
"Content-Type": "application/json",
|
|
851
|
+
...config.apiKey && { Authorization: `Bearer ${config.apiKey}` }
|
|
852
|
+
},
|
|
718
853
|
body: JSON.stringify(body)
|
|
719
854
|
}).catch(() => {
|
|
720
855
|
});
|
|
@@ -736,7 +871,11 @@ async function quickVerify(config, credentials) {
|
|
|
736
871
|
return {
|
|
737
872
|
identityVerified: result.identityVerified,
|
|
738
873
|
policyAllowed: result.policyAllowed,
|
|
739
|
-
reason: result.denialReasons?.[0]
|
|
874
|
+
reason: result.denialReasons?.[0],
|
|
875
|
+
...isVerificationUnavailable(result) && {
|
|
876
|
+
unavailable: true,
|
|
877
|
+
retryAfterMs: unavailableRetryAfterSeconds(result) * 1e3
|
|
878
|
+
}
|
|
740
879
|
};
|
|
741
880
|
}
|
|
742
881
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -746,6 +885,7 @@ async function quickVerify(config, credentials) {
|
|
|
746
885
|
extractCredentials,
|
|
747
886
|
fetchRoutes,
|
|
748
887
|
hasCredentials,
|
|
888
|
+
parseRetryAfterMs,
|
|
749
889
|
quickVerify,
|
|
750
890
|
recordDecision,
|
|
751
891
|
reportAttempt,
|