@astrasyncai/verification-gateway 5.12.0 → 5.14.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 +63 -19
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +63 -19
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.js +26 -9
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +26 -9
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.js +63 -19
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +63 -19
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.js +26 -9
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +26 -9
- 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 +53 -18
- package/dist/bin/astrasync-codex-hook.js +53 -18
- package/dist/bin/astrasync-guard.js +53 -18
- package/dist/bin/astrasync.js +54 -19
- package/dist/browser/background.js +53 -18
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +53 -18
- 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 +53 -18
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +53 -18
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +53 -18
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +53 -18
- package/dist/cursor/extension.mjs.map +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 +32 -4
- package/dist/edge-core/index.d.ts +32 -4
- package/dist/edge-core/index.js +53 -18
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +53 -18
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +53 -18
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +53 -18
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/index.d.mts +2 -12
- package/dist/index.d.ts +2 -12
- package/dist/index.js +63 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +63 -19
- package/dist/index.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/verify.d.mts +0 -10
- package/dist/verify.d.ts +0 -10
- package/dist/verify.js +36 -10
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +36 -10
- package/dist/verify.mjs.map +1 -1
- package/package.json +3 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var SDK_VERSION = "5.
|
|
2
|
+
var SDK_VERSION = "5.14.0";
|
|
3
3
|
|
|
4
4
|
// src/http.ts
|
|
5
5
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -209,7 +209,7 @@ var DEFAULT_CONFIG = {
|
|
|
209
209
|
};
|
|
210
210
|
var initCheckPerformed = false;
|
|
211
211
|
var deprecationWarningShown = false;
|
|
212
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
212
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey, counterparty) {
|
|
213
213
|
initCheckPerformed = true;
|
|
214
214
|
try {
|
|
215
215
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -227,7 +227,8 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
227
227
|
);
|
|
228
228
|
}
|
|
229
229
|
if (apiKey) {
|
|
230
|
-
const
|
|
230
|
+
const q = counterparty?.id ? `?counterpartyId=${encodeURIComponent(counterparty.id)}` : counterparty?.url ? `?counterpartyUrl=${encodeURIComponent(counterparty.url)}` : "";
|
|
231
|
+
const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check${q}`, {
|
|
231
232
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
232
233
|
});
|
|
233
234
|
if (selfCheck.status === 401) {
|
|
@@ -239,6 +240,13 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
239
240
|
console.error(message);
|
|
240
241
|
} else if (selfCheck.ok) {
|
|
241
242
|
const body = await selfCheck.json().catch(() => ({}));
|
|
243
|
+
if (body.counterparty && body.counterparty.canVerify === false) {
|
|
244
|
+
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.`;
|
|
245
|
+
if (strictInit) {
|
|
246
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
247
|
+
}
|
|
248
|
+
console.error(message);
|
|
249
|
+
}
|
|
242
250
|
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
243
251
|
console.warn(
|
|
244
252
|
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
@@ -377,11 +385,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
377
385
|
const isMisconfig = source === "merchant_misconfig";
|
|
378
386
|
const urls = options.urls;
|
|
379
387
|
const guidance = isMisconfig ? {
|
|
380
|
-
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or
|
|
388
|
+
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.",
|
|
381
389
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
382
390
|
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
383
391
|
steps: [
|
|
384
|
-
"Report the failure to the site operator \u2014 their AstraSync API key needs
|
|
392
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs replacing",
|
|
385
393
|
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
386
394
|
]
|
|
387
395
|
} : isApiError ? {
|
|
@@ -593,12 +601,13 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
593
601
|
};
|
|
594
602
|
}
|
|
595
603
|
if (!response.ok) {
|
|
596
|
-
|
|
604
|
+
const keyMismatch = response.status === 403 && data?.error === "COUNTERPARTY_KEY_MISMATCH";
|
|
605
|
+
if (response.status === 401 || keyMismatch) {
|
|
597
606
|
return {
|
|
598
607
|
success: false,
|
|
599
608
|
error: data.message || data.error || "Integration API key rejected",
|
|
600
609
|
misconfig: true,
|
|
601
|
-
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
610
|
+
misconfigCode: keyMismatch ? "counterparty_key_mismatch" : typeof data?.code === "string" ? data.code : void 0,
|
|
602
611
|
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
603
612
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
604
613
|
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
@@ -631,14 +640,22 @@ async function verify(config, request, options) {
|
|
|
631
640
|
mergedConfig.apiBaseUrl,
|
|
632
641
|
mergedConfig.debug,
|
|
633
642
|
true,
|
|
634
|
-
mergedConfig.apiKey
|
|
643
|
+
mergedConfig.apiKey,
|
|
644
|
+
{
|
|
645
|
+
id: mergedConfig.counterpartyId,
|
|
646
|
+
url: mergedConfig.counterpartyUrl ?? request.counterpartyUrl
|
|
647
|
+
}
|
|
635
648
|
);
|
|
636
649
|
} else {
|
|
637
650
|
void performInitCheck(
|
|
638
651
|
mergedConfig.apiBaseUrl,
|
|
639
652
|
mergedConfig.debug,
|
|
640
653
|
false,
|
|
641
|
-
mergedConfig.apiKey
|
|
654
|
+
mergedConfig.apiKey,
|
|
655
|
+
{
|
|
656
|
+
id: mergedConfig.counterpartyId,
|
|
657
|
+
url: mergedConfig.counterpartyUrl ?? request.counterpartyUrl
|
|
658
|
+
}
|
|
642
659
|
);
|
|
643
660
|
}
|
|
644
661
|
}
|
|
@@ -827,6 +844,7 @@ async function recordDecision(config, sessionId, decision, reason) {
|
|
|
827
844
|
}).catch(() => {
|
|
828
845
|
});
|
|
829
846
|
}
|
|
847
|
+
var refusedPolicyReads = /* @__PURE__ */ new Set();
|
|
830
848
|
async function fetchRoutes(config, counterpartyId) {
|
|
831
849
|
if (!counterpartyId) return null;
|
|
832
850
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -839,7 +857,15 @@ async function fetchRoutes(config, counterpartyId) {
|
|
|
839
857
|
`${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/routes`,
|
|
840
858
|
{ method: "GET", headers }
|
|
841
859
|
);
|
|
842
|
-
if (!response.ok)
|
|
860
|
+
if (!response.ok) {
|
|
861
|
+
if ((response.status === 401 || response.status === 403 || response.status === 404) && !refusedPolicyReads.has(counterpartyId)) {
|
|
862
|
+
refusedPolicyReads.add(counterpartyId);
|
|
863
|
+
console.error(
|
|
864
|
+
`[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.`
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
return null;
|
|
868
|
+
}
|
|
843
869
|
const body = await response.json();
|
|
844
870
|
return body.data?.routes ?? [];
|
|
845
871
|
} catch {
|
|
@@ -1602,6 +1628,11 @@ async function withBudget(promise, ms) {
|
|
|
1602
1628
|
if (timer) clearTimeout(timer);
|
|
1603
1629
|
}
|
|
1604
1630
|
}
|
|
1631
|
+
var CONTAINER_ID = (() => {
|
|
1632
|
+
const c = globalThis.crypto;
|
|
1633
|
+
if (c?.randomUUID) return c.randomUUID();
|
|
1634
|
+
return `c-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
|
|
1635
|
+
})();
|
|
1605
1636
|
var destKeyOf = (d) => `${d.apiBaseUrl}\0${d.apiKey ?? ""}\0${d.counterparty}\0${d.adapter ?? ""}`;
|
|
1606
1637
|
var BeaconBuffer = class {
|
|
1607
1638
|
constructor(options = {}) {
|
|
@@ -1609,6 +1640,7 @@ var BeaconBuffer = class {
|
|
|
1609
1640
|
this.droppedSinceLast = 0;
|
|
1610
1641
|
this.droppedTotal = 0;
|
|
1611
1642
|
this.deliveredTotal = 0;
|
|
1643
|
+
this.enqueuedTotal = 0;
|
|
1612
1644
|
this.backoffUntil = 0;
|
|
1613
1645
|
this.collapse = /* @__PURE__ */ new Map();
|
|
1614
1646
|
/** Keys the backend answered 401 for — later batches go unauthenticated. */
|
|
@@ -1621,13 +1653,16 @@ var BeaconBuffer = class {
|
|
|
1621
1653
|
collapseMaxKeys: options.collapseMaxKeys ?? 1e3,
|
|
1622
1654
|
requestTimeoutMs: options.requestTimeoutMs ?? 1e4,
|
|
1623
1655
|
retryBackoffMs: options.retryBackoffMs ?? 1e3,
|
|
1656
|
+
holdRepeats: options.holdRepeats ?? false,
|
|
1657
|
+
containerId: options.containerId ?? CONTAINER_ID,
|
|
1624
1658
|
now: options.now ?? Date.now
|
|
1625
1659
|
};
|
|
1626
1660
|
}
|
|
1627
1661
|
/**
|
|
1628
1662
|
* Queue one beacon. With a `collapseKey`, a repeat inside the window is
|
|
1629
|
-
* merged into
|
|
1630
|
-
*
|
|
1663
|
+
* merged into this key's item while that item is still queued (not yet in
|
|
1664
|
+
* flight). Once it has left, the repeat becomes a new item, sendable on
|
|
1665
|
+
* this flush — nothing waits for a later invocation (round 27.6).
|
|
1631
1666
|
*/
|
|
1632
1667
|
enqueue(dest, item, collapseKey) {
|
|
1633
1668
|
const now = this.opts.now();
|
|
@@ -1640,12 +1675,15 @@ var BeaconBuffer = class {
|
|
|
1640
1675
|
return;
|
|
1641
1676
|
}
|
|
1642
1677
|
}
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1678
|
+
if (this.opts.holdRepeats) {
|
|
1679
|
+
entry.held = this.push(
|
|
1680
|
+
dest,
|
|
1681
|
+
{ ...item, repeatCount: 1 },
|
|
1682
|
+
entry.firstSeenAt + this.opts.collapseWindowMs
|
|
1683
|
+
);
|
|
1684
|
+
return;
|
|
1685
|
+
}
|
|
1686
|
+
entry.first = this.push(dest, { ...item, repeatCount: 1 }, now);
|
|
1649
1687
|
return;
|
|
1650
1688
|
}
|
|
1651
1689
|
this.collapse.delete(collapseKey);
|
|
@@ -1681,6 +1719,7 @@ var BeaconBuffer = class {
|
|
|
1681
1719
|
droppedSinceLast: this.droppedSinceLast,
|
|
1682
1720
|
droppedTotal: this.droppedTotal,
|
|
1683
1721
|
deliveredTotal: this.deliveredTotal,
|
|
1722
|
+
enqueuedTotal: this.enqueuedTotal,
|
|
1684
1723
|
flushing: this.inFlight !== void 0
|
|
1685
1724
|
};
|
|
1686
1725
|
}
|
|
@@ -1695,6 +1734,7 @@ var BeaconBuffer = class {
|
|
|
1695
1734
|
inFlight: false
|
|
1696
1735
|
};
|
|
1697
1736
|
this.queue.push(entry);
|
|
1737
|
+
this.enqueuedTotal += 1;
|
|
1698
1738
|
return entry;
|
|
1699
1739
|
}
|
|
1700
1740
|
dropOldest() {
|
|
@@ -1740,7 +1780,11 @@ var BeaconBuffer = class {
|
|
|
1740
1780
|
droppedSinceLast: reportedDropped,
|
|
1741
1781
|
queueDepth: this.queue.length,
|
|
1742
1782
|
adapter: dest.adapter ?? "edge-core",
|
|
1743
|
-
version: SDK_VERSION
|
|
1783
|
+
version: SDK_VERSION,
|
|
1784
|
+
containerId: this.opts.containerId,
|
|
1785
|
+
enqueuedTotal: this.enqueuedTotal,
|
|
1786
|
+
deliveredTotal: this.deliveredTotal,
|
|
1787
|
+
droppedTotal: this.droppedTotal
|
|
1744
1788
|
};
|
|
1745
1789
|
const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
1746
1790
|
const response = await withBudget(
|