@astrasyncai/verification-gateway 3.12.0 → 4.0.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/adapter-interface/interface.d.mts +2 -2
- package/dist/adapter-interface/interface.d.ts +2 -2
- package/dist/adapters/express.d.mts +2 -2
- package/dist/adapters/express.d.ts +2 -2
- package/dist/adapters/express.js +85 -8
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +85 -8
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +1 -1
- package/dist/adapters/mcp.d.ts +1 -1
- package/dist/adapters/mcp.js +90 -8
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +90 -8
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +2 -2
- package/dist/adapters/nextjs.d.ts +2 -2
- package/dist/adapters/nextjs.js +86 -8
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +86 -8
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +2 -2
- package/dist/adapters/sdk.d.ts +2 -2
- package/dist/adapters/sdk.js +71 -8
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +71 -8
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.d.mts +2 -2
- package/dist/agent/index.d.ts +2 -2
- package/dist/bin/astrasync-claude-hook.js +71 -8
- package/dist/bin/astrasync-codex-hook.js +71 -8
- package/dist/bin/astrasync-guard.js +71 -8
- package/dist/bin/astrasync.js +71 -8
- package/dist/browser/background.js +71 -8
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +71 -8
- package/dist/browser/background.mjs.map +1 -1
- package/dist/browser/browser-adapter.d.mts +2 -2
- package/dist/browser/browser-adapter.d.ts +2 -2
- package/dist/claude-code/claude-code-adapter.d.mts +2 -2
- package/dist/claude-code/claude-code-adapter.d.ts +2 -2
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/codex/index.d.mts +2 -2
- package/dist/codex/index.d.ts +2 -2
- package/dist/codex/index.js +71 -8
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +71 -8
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/cursor-adapter.d.mts +2 -2
- package/dist/cursor/cursor-adapter.d.ts +2 -2
- package/dist/cursor/extension.d.mts +2 -2
- package/dist/cursor/extension.d.ts +2 -2
- package/dist/cursor/extension.js +71 -8
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +71 -8
- 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/{express-B39o89gf.d.mts → express-BZajRs4i.d.mts} +1 -1
- package/dist/{express-BuxKNO_q.d.ts → express-CjCUB1k7.d.ts} +1 -1
- package/dist/gateway/gateway.d.mts +2 -2
- package/dist/gateway/gateway.d.ts +2 -2
- package/dist/gateway/gateway.js +71 -8
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +71 -8
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +2 -2
- package/dist/git-trigger/git-hooks.d.ts +2 -2
- package/dist/{index-DME3w3lf.d.mts → index-B0cyMZDL.d.mts} +1 -1
- package/dist/{index-CqydB4ks.d.mts → index-BRYteOqO.d.mts} +1 -1
- package/dist/{index-BG62SXso.d.ts → index-BZQdVqNw.d.ts} +1 -1
- package/dist/{index-CLHdqs2M.d.ts → index-adgKhujR.d.ts} +1 -1
- package/dist/index.d.mts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +119 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +119 -8
- package/dist/index.mjs.map +1 -1
- package/dist/local-evaluator/evaluator.d.mts +2 -2
- package/dist/local-evaluator/evaluator.d.ts +2 -2
- package/dist/{nextjs-Ddlw_J1J.d.ts → nextjs-D_iFf5k-.d.ts} +1 -1
- package/dist/{nextjs-D74W7wt-.d.mts → nextjs-DeUTnOBd.d.mts} +1 -1
- package/dist/{sdk-CT7gdkfR.d.ts → sdk-BM3mwEAq.d.ts} +1 -1
- package/dist/{sdk-Bn6bj7kt.d.mts → sdk-_il1Q41f.d.mts} +1 -1
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/{types-BntuzEEn.d.mts → types-BcDf9Kk0.d.mts} +15 -0
- package/dist/{types-DHu7m9HI.d.ts → types-CHKCgDFC.d.ts} +1 -1
- package/dist/{types-Djw4GLtz.d.mts → types-DfnP7JiM.d.mts} +1 -1
- package/dist/{types-SDu4Llbe.d.ts → types-fTQD448H.d.ts} +15 -0
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +4 -2
- package/dist/verify.d.ts +4 -2
- package/dist/verify.js +76 -8
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +75 -8
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -3701,7 +3701,7 @@ function getTrustLevel(score) {
|
|
|
3701
3701
|
}
|
|
3702
3702
|
|
|
3703
3703
|
// src/version.ts
|
|
3704
|
-
var SDK_VERSION = "
|
|
3704
|
+
var SDK_VERSION = "4.0.0";
|
|
3705
3705
|
|
|
3706
3706
|
// src/well-known.ts
|
|
3707
3707
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -3727,7 +3727,7 @@ var DEFAULT_CONFIG = {
|
|
|
3727
3727
|
};
|
|
3728
3728
|
var initCheckPerformed = false;
|
|
3729
3729
|
var deprecationWarningShown = false;
|
|
3730
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
3730
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
3731
3731
|
initCheckPerformed = true;
|
|
3732
3732
|
try {
|
|
3733
3733
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -3744,6 +3744,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
|
3744
3744
|
`[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
|
|
3745
3745
|
);
|
|
3746
3746
|
}
|
|
3747
|
+
if (apiKey) {
|
|
3748
|
+
const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
|
|
3749
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3750
|
+
});
|
|
3751
|
+
if (selfCheck.status === 401) {
|
|
3752
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
3753
|
+
const message = `[VerificationGateway] the configured AstraSync API key was REJECTED at startup (${body.code ?? "api_key_invalid"}: ${body.message ?? "invalid key"}). Every inbound agent will be turned away until the key is rotated` + (body.remediation?.manageUrl ? ` at ${body.remediation.manageUrl}` : "") + `.`;
|
|
3754
|
+
if (strictInit) {
|
|
3755
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
3756
|
+
}
|
|
3757
|
+
console.error(message);
|
|
3758
|
+
} else if (selfCheck.ok) {
|
|
3759
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
3760
|
+
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
3761
|
+
console.warn(
|
|
3762
|
+
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
3763
|
+
);
|
|
3764
|
+
} else if (debug) {
|
|
3765
|
+
console.log("[VerificationGateway] API key self-check passed");
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3747
3769
|
} catch (err) {
|
|
3748
3770
|
if (strictInit) {
|
|
3749
3771
|
throw err;
|
|
@@ -3821,8 +3843,17 @@ function cacheResult(request, result, configuredTtl, counterpartyId) {
|
|
|
3821
3843
|
function createGuidanceResponse(_config, reason, options = {}) {
|
|
3822
3844
|
const source = options.source ?? "no_credentials";
|
|
3823
3845
|
const isApiError = source === "api_error";
|
|
3846
|
+
const isMisconfig = source === "merchant_misconfig";
|
|
3824
3847
|
const urls = options.urls;
|
|
3825
|
-
const guidance =
|
|
3848
|
+
const guidance = isMisconfig ? {
|
|
3849
|
+
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or rotated). Your identity and the AstraSync platform are fine \u2014 contact the site operator. Retrying will not help.",
|
|
3850
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
3851
|
+
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
3852
|
+
steps: [
|
|
3853
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
|
|
3854
|
+
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
3855
|
+
]
|
|
3856
|
+
} : isApiError ? {
|
|
3826
3857
|
message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
|
|
3827
3858
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
3828
3859
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
@@ -3860,13 +3891,22 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
3860
3891
|
// partners (and their custom onDenied handlers) can branch on
|
|
3861
3892
|
// dimension. Without this, the synthesised stub was indistinguishable
|
|
3862
3893
|
// from a real policy deny.
|
|
3863
|
-
failures:
|
|
3894
|
+
failures: isMisconfig ? [
|
|
3895
|
+
{
|
|
3896
|
+
dimension: "verify_access.merchant_misconfigured",
|
|
3897
|
+
message: reason ?? "The integration API key was rejected by AstraSync",
|
|
3898
|
+
guidance: guidance.message
|
|
3899
|
+
}
|
|
3900
|
+
] : isApiError ? [
|
|
3864
3901
|
{
|
|
3865
3902
|
dimension: "verify_access.api_error",
|
|
3866
3903
|
message: reason ?? "Verification temporarily unavailable",
|
|
3867
3904
|
guidance: guidance.message
|
|
3868
3905
|
}
|
|
3869
3906
|
] : void 0,
|
|
3907
|
+
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
3908
|
+
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
3909
|
+
...isMisconfig && { misconfigured: true },
|
|
3870
3910
|
correlationId: options.correlationId,
|
|
3871
3911
|
attemptId: options.attemptId,
|
|
3872
3912
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
@@ -3921,7 +3961,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
3921
3961
|
const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
3922
3962
|
method: "POST",
|
|
3923
3963
|
headers,
|
|
3924
|
-
body: JSON.stringify(body)
|
|
3964
|
+
body: JSON.stringify(body),
|
|
3965
|
+
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
3925
3966
|
});
|
|
3926
3967
|
const data = await response.json();
|
|
3927
3968
|
if (response.status === 410) {
|
|
@@ -3945,6 +3986,17 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
3945
3986
|
};
|
|
3946
3987
|
}
|
|
3947
3988
|
if (!response.ok) {
|
|
3989
|
+
if (response.status === 401) {
|
|
3990
|
+
return {
|
|
3991
|
+
success: false,
|
|
3992
|
+
error: data.message || data.error || "Integration API key rejected",
|
|
3993
|
+
misconfig: true,
|
|
3994
|
+
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
3995
|
+
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
3996
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
3997
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
3998
|
+
};
|
|
3999
|
+
}
|
|
3948
4000
|
return {
|
|
3949
4001
|
success: false,
|
|
3950
4002
|
error: data.message || data.error || `API returned ${response.status}`,
|
|
@@ -3966,9 +4018,19 @@ async function verify(config, request, options) {
|
|
|
3966
4018
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
3967
4019
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
3968
4020
|
if (mergedConfig.strictInit) {
|
|
3969
|
-
await performInitCheck(
|
|
4021
|
+
await performInitCheck(
|
|
4022
|
+
mergedConfig.apiBaseUrl,
|
|
4023
|
+
mergedConfig.debug,
|
|
4024
|
+
true,
|
|
4025
|
+
mergedConfig.apiKey
|
|
4026
|
+
);
|
|
3970
4027
|
} else {
|
|
3971
|
-
void performInitCheck(
|
|
4028
|
+
void performInitCheck(
|
|
4029
|
+
mergedConfig.apiBaseUrl,
|
|
4030
|
+
mergedConfig.debug,
|
|
4031
|
+
false,
|
|
4032
|
+
mergedConfig.apiKey
|
|
4033
|
+
);
|
|
3972
4034
|
}
|
|
3973
4035
|
}
|
|
3974
4036
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
@@ -4007,9 +4069,10 @@ async function verify(config, request, options) {
|
|
|
4007
4069
|
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
4008
4070
|
if (!apiResponse.success) {
|
|
4009
4071
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
4010
|
-
source: "api_error",
|
|
4072
|
+
source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
|
|
4011
4073
|
correlationId: apiResponse.correlationId,
|
|
4012
4074
|
attemptId: apiResponse.attemptId,
|
|
4075
|
+
remediation: apiResponse.remediation,
|
|
4013
4076
|
urls
|
|
4014
4077
|
});
|
|
4015
4078
|
}
|
|
@@ -3700,7 +3700,7 @@ function getTrustLevel(score) {
|
|
|
3700
3700
|
}
|
|
3701
3701
|
|
|
3702
3702
|
// src/version.ts
|
|
3703
|
-
var SDK_VERSION = "
|
|
3703
|
+
var SDK_VERSION = "4.0.0";
|
|
3704
3704
|
|
|
3705
3705
|
// src/well-known.ts
|
|
3706
3706
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -3726,7 +3726,7 @@ var DEFAULT_CONFIG = {
|
|
|
3726
3726
|
};
|
|
3727
3727
|
var initCheckPerformed = false;
|
|
3728
3728
|
var deprecationWarningShown = false;
|
|
3729
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
3729
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
3730
3730
|
initCheckPerformed = true;
|
|
3731
3731
|
try {
|
|
3732
3732
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -3743,6 +3743,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
|
3743
3743
|
`[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
|
|
3744
3744
|
);
|
|
3745
3745
|
}
|
|
3746
|
+
if (apiKey) {
|
|
3747
|
+
const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
|
|
3748
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3749
|
+
});
|
|
3750
|
+
if (selfCheck.status === 401) {
|
|
3751
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
3752
|
+
const message = `[VerificationGateway] the configured AstraSync API key was REJECTED at startup (${body.code ?? "api_key_invalid"}: ${body.message ?? "invalid key"}). Every inbound agent will be turned away until the key is rotated` + (body.remediation?.manageUrl ? ` at ${body.remediation.manageUrl}` : "") + `.`;
|
|
3753
|
+
if (strictInit) {
|
|
3754
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
3755
|
+
}
|
|
3756
|
+
console.error(message);
|
|
3757
|
+
} else if (selfCheck.ok) {
|
|
3758
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
3759
|
+
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
3760
|
+
console.warn(
|
|
3761
|
+
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
3762
|
+
);
|
|
3763
|
+
} else if (debug) {
|
|
3764
|
+
console.log("[VerificationGateway] API key self-check passed");
|
|
3765
|
+
}
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3746
3768
|
} catch (err) {
|
|
3747
3769
|
if (strictInit) {
|
|
3748
3770
|
throw err;
|
|
@@ -3820,8 +3842,17 @@ function cacheResult(request, result, configuredTtl, counterpartyId) {
|
|
|
3820
3842
|
function createGuidanceResponse(_config, reason, options = {}) {
|
|
3821
3843
|
const source = options.source ?? "no_credentials";
|
|
3822
3844
|
const isApiError = source === "api_error";
|
|
3845
|
+
const isMisconfig = source === "merchant_misconfig";
|
|
3823
3846
|
const urls = options.urls;
|
|
3824
|
-
const guidance =
|
|
3847
|
+
const guidance = isMisconfig ? {
|
|
3848
|
+
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or rotated). Your identity and the AstraSync platform are fine \u2014 contact the site operator. Retrying will not help.",
|
|
3849
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
3850
|
+
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
3851
|
+
steps: [
|
|
3852
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
|
|
3853
|
+
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
3854
|
+
]
|
|
3855
|
+
} : isApiError ? {
|
|
3825
3856
|
message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
|
|
3826
3857
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
3827
3858
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
@@ -3859,13 +3890,22 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
3859
3890
|
// partners (and their custom onDenied handlers) can branch on
|
|
3860
3891
|
// dimension. Without this, the synthesised stub was indistinguishable
|
|
3861
3892
|
// from a real policy deny.
|
|
3862
|
-
failures:
|
|
3893
|
+
failures: isMisconfig ? [
|
|
3894
|
+
{
|
|
3895
|
+
dimension: "verify_access.merchant_misconfigured",
|
|
3896
|
+
message: reason ?? "The integration API key was rejected by AstraSync",
|
|
3897
|
+
guidance: guidance.message
|
|
3898
|
+
}
|
|
3899
|
+
] : isApiError ? [
|
|
3863
3900
|
{
|
|
3864
3901
|
dimension: "verify_access.api_error",
|
|
3865
3902
|
message: reason ?? "Verification temporarily unavailable",
|
|
3866
3903
|
guidance: guidance.message
|
|
3867
3904
|
}
|
|
3868
3905
|
] : void 0,
|
|
3906
|
+
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
3907
|
+
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
3908
|
+
...isMisconfig && { misconfigured: true },
|
|
3869
3909
|
correlationId: options.correlationId,
|
|
3870
3910
|
attemptId: options.attemptId,
|
|
3871
3911
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
@@ -3920,7 +3960,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
3920
3960
|
const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
3921
3961
|
method: "POST",
|
|
3922
3962
|
headers,
|
|
3923
|
-
body: JSON.stringify(body)
|
|
3963
|
+
body: JSON.stringify(body),
|
|
3964
|
+
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
3924
3965
|
});
|
|
3925
3966
|
const data = await response.json();
|
|
3926
3967
|
if (response.status === 410) {
|
|
@@ -3944,6 +3985,17 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
3944
3985
|
};
|
|
3945
3986
|
}
|
|
3946
3987
|
if (!response.ok) {
|
|
3988
|
+
if (response.status === 401) {
|
|
3989
|
+
return {
|
|
3990
|
+
success: false,
|
|
3991
|
+
error: data.message || data.error || "Integration API key rejected",
|
|
3992
|
+
misconfig: true,
|
|
3993
|
+
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
3994
|
+
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
3995
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
3996
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
3997
|
+
};
|
|
3998
|
+
}
|
|
3947
3999
|
return {
|
|
3948
4000
|
success: false,
|
|
3949
4001
|
error: data.message || data.error || `API returned ${response.status}`,
|
|
@@ -3965,9 +4017,19 @@ async function verify(config, request, options) {
|
|
|
3965
4017
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
3966
4018
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
3967
4019
|
if (mergedConfig.strictInit) {
|
|
3968
|
-
await performInitCheck(
|
|
4020
|
+
await performInitCheck(
|
|
4021
|
+
mergedConfig.apiBaseUrl,
|
|
4022
|
+
mergedConfig.debug,
|
|
4023
|
+
true,
|
|
4024
|
+
mergedConfig.apiKey
|
|
4025
|
+
);
|
|
3969
4026
|
} else {
|
|
3970
|
-
void performInitCheck(
|
|
4027
|
+
void performInitCheck(
|
|
4028
|
+
mergedConfig.apiBaseUrl,
|
|
4029
|
+
mergedConfig.debug,
|
|
4030
|
+
false,
|
|
4031
|
+
mergedConfig.apiKey
|
|
4032
|
+
);
|
|
3971
4033
|
}
|
|
3972
4034
|
}
|
|
3973
4035
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
@@ -4006,9 +4068,10 @@ async function verify(config, request, options) {
|
|
|
4006
4068
|
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
4007
4069
|
if (!apiResponse.success) {
|
|
4008
4070
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
4009
|
-
source: "api_error",
|
|
4071
|
+
source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
|
|
4010
4072
|
correlationId: apiResponse.correlationId,
|
|
4011
4073
|
attemptId: apiResponse.attemptId,
|
|
4074
|
+
remediation: apiResponse.remediation,
|
|
4012
4075
|
urls
|
|
4013
4076
|
});
|
|
4014
4077
|
}
|
|
@@ -4609,7 +4609,7 @@ function getTrustLevel(score) {
|
|
|
4609
4609
|
}
|
|
4610
4610
|
|
|
4611
4611
|
// src/version.ts
|
|
4612
|
-
var SDK_VERSION = "
|
|
4612
|
+
var SDK_VERSION = "4.0.0";
|
|
4613
4613
|
|
|
4614
4614
|
// src/well-known.ts
|
|
4615
4615
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -4635,7 +4635,7 @@ var DEFAULT_CONFIG = {
|
|
|
4635
4635
|
};
|
|
4636
4636
|
var initCheckPerformed = false;
|
|
4637
4637
|
var deprecationWarningShown = false;
|
|
4638
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
4638
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
4639
4639
|
initCheckPerformed = true;
|
|
4640
4640
|
try {
|
|
4641
4641
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -4652,6 +4652,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
|
4652
4652
|
`[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
|
|
4653
4653
|
);
|
|
4654
4654
|
}
|
|
4655
|
+
if (apiKey) {
|
|
4656
|
+
const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
|
|
4657
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4658
|
+
});
|
|
4659
|
+
if (selfCheck.status === 401) {
|
|
4660
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
4661
|
+
const message = `[VerificationGateway] the configured AstraSync API key was REJECTED at startup (${body.code ?? "api_key_invalid"}: ${body.message ?? "invalid key"}). Every inbound agent will be turned away until the key is rotated` + (body.remediation?.manageUrl ? ` at ${body.remediation.manageUrl}` : "") + `.`;
|
|
4662
|
+
if (strictInit) {
|
|
4663
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
4664
|
+
}
|
|
4665
|
+
console.error(message);
|
|
4666
|
+
} else if (selfCheck.ok) {
|
|
4667
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
4668
|
+
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
4669
|
+
console.warn(
|
|
4670
|
+
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
4671
|
+
);
|
|
4672
|
+
} else if (debug) {
|
|
4673
|
+
console.log("[VerificationGateway] API key self-check passed");
|
|
4674
|
+
}
|
|
4675
|
+
}
|
|
4676
|
+
}
|
|
4655
4677
|
} catch (err) {
|
|
4656
4678
|
if (strictInit) {
|
|
4657
4679
|
throw err;
|
|
@@ -4729,8 +4751,17 @@ function cacheResult(request2, result, configuredTtl, counterpartyId) {
|
|
|
4729
4751
|
function createGuidanceResponse(_config, reason, options = {}) {
|
|
4730
4752
|
const source = options.source ?? "no_credentials";
|
|
4731
4753
|
const isApiError = source === "api_error";
|
|
4754
|
+
const isMisconfig = source === "merchant_misconfig";
|
|
4732
4755
|
const urls = options.urls;
|
|
4733
|
-
const guidance =
|
|
4756
|
+
const guidance = isMisconfig ? {
|
|
4757
|
+
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or rotated). Your identity and the AstraSync platform are fine \u2014 contact the site operator. Retrying will not help.",
|
|
4758
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
4759
|
+
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
4760
|
+
steps: [
|
|
4761
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
|
|
4762
|
+
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
4763
|
+
]
|
|
4764
|
+
} : isApiError ? {
|
|
4734
4765
|
message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
|
|
4735
4766
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
4736
4767
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
@@ -4768,13 +4799,22 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
4768
4799
|
// partners (and their custom onDenied handlers) can branch on
|
|
4769
4800
|
// dimension. Without this, the synthesised stub was indistinguishable
|
|
4770
4801
|
// from a real policy deny.
|
|
4771
|
-
failures:
|
|
4802
|
+
failures: isMisconfig ? [
|
|
4803
|
+
{
|
|
4804
|
+
dimension: "verify_access.merchant_misconfigured",
|
|
4805
|
+
message: reason ?? "The integration API key was rejected by AstraSync",
|
|
4806
|
+
guidance: guidance.message
|
|
4807
|
+
}
|
|
4808
|
+
] : isApiError ? [
|
|
4772
4809
|
{
|
|
4773
4810
|
dimension: "verify_access.api_error",
|
|
4774
4811
|
message: reason ?? "Verification temporarily unavailable",
|
|
4775
4812
|
guidance: guidance.message
|
|
4776
4813
|
}
|
|
4777
4814
|
] : void 0,
|
|
4815
|
+
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
4816
|
+
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
4817
|
+
...isMisconfig && { misconfigured: true },
|
|
4778
4818
|
correlationId: options.correlationId,
|
|
4779
4819
|
attemptId: options.attemptId,
|
|
4780
4820
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
@@ -4829,7 +4869,8 @@ async function callVerifyAccessAPI(config, request2) {
|
|
|
4829
4869
|
const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
4830
4870
|
method: "POST",
|
|
4831
4871
|
headers,
|
|
4832
|
-
body: JSON.stringify(body)
|
|
4872
|
+
body: JSON.stringify(body),
|
|
4873
|
+
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
4833
4874
|
});
|
|
4834
4875
|
const data = await response.json();
|
|
4835
4876
|
if (response.status === 410) {
|
|
@@ -4853,6 +4894,17 @@ async function callVerifyAccessAPI(config, request2) {
|
|
|
4853
4894
|
};
|
|
4854
4895
|
}
|
|
4855
4896
|
if (!response.ok) {
|
|
4897
|
+
if (response.status === 401) {
|
|
4898
|
+
return {
|
|
4899
|
+
success: false,
|
|
4900
|
+
error: data.message || data.error || "Integration API key rejected",
|
|
4901
|
+
misconfig: true,
|
|
4902
|
+
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
4903
|
+
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
4904
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
4905
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
4906
|
+
};
|
|
4907
|
+
}
|
|
4856
4908
|
return {
|
|
4857
4909
|
success: false,
|
|
4858
4910
|
error: data.message || data.error || `API returned ${response.status}`,
|
|
@@ -4874,9 +4926,19 @@ async function verify(config, request2, options) {
|
|
|
4874
4926
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
4875
4927
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
4876
4928
|
if (mergedConfig.strictInit) {
|
|
4877
|
-
await performInitCheck(
|
|
4929
|
+
await performInitCheck(
|
|
4930
|
+
mergedConfig.apiBaseUrl,
|
|
4931
|
+
mergedConfig.debug,
|
|
4932
|
+
true,
|
|
4933
|
+
mergedConfig.apiKey
|
|
4934
|
+
);
|
|
4878
4935
|
} else {
|
|
4879
|
-
void performInitCheck(
|
|
4936
|
+
void performInitCheck(
|
|
4937
|
+
mergedConfig.apiBaseUrl,
|
|
4938
|
+
mergedConfig.debug,
|
|
4939
|
+
false,
|
|
4940
|
+
mergedConfig.apiKey
|
|
4941
|
+
);
|
|
4880
4942
|
}
|
|
4881
4943
|
}
|
|
4882
4944
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
@@ -4915,9 +4977,10 @@ async function verify(config, request2, options) {
|
|
|
4915
4977
|
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
4916
4978
|
if (!apiResponse.success) {
|
|
4917
4979
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
4918
|
-
source: "api_error",
|
|
4980
|
+
source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
|
|
4919
4981
|
correlationId: apiResponse.correlationId,
|
|
4920
4982
|
attemptId: apiResponse.attemptId,
|
|
4983
|
+
remediation: apiResponse.remediation,
|
|
4921
4984
|
urls
|
|
4922
4985
|
});
|
|
4923
4986
|
}
|
package/dist/bin/astrasync.js
CHANGED
|
@@ -5000,7 +5000,7 @@ var SDK_VERSION;
|
|
|
5000
5000
|
var init_version = __esm({
|
|
5001
5001
|
"src/version.ts"() {
|
|
5002
5002
|
"use strict";
|
|
5003
|
-
SDK_VERSION = "
|
|
5003
|
+
SDK_VERSION = "4.0.0";
|
|
5004
5004
|
}
|
|
5005
5005
|
});
|
|
5006
5006
|
|
|
@@ -5018,7 +5018,7 @@ var init_well_known = __esm({
|
|
|
5018
5018
|
});
|
|
5019
5019
|
|
|
5020
5020
|
// src/verify.ts
|
|
5021
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
5021
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
5022
5022
|
initCheckPerformed = true;
|
|
5023
5023
|
try {
|
|
5024
5024
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -5035,6 +5035,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
|
5035
5035
|
`[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
|
|
5036
5036
|
);
|
|
5037
5037
|
}
|
|
5038
|
+
if (apiKey) {
|
|
5039
|
+
const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
|
|
5040
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
5041
|
+
});
|
|
5042
|
+
if (selfCheck.status === 401) {
|
|
5043
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
5044
|
+
const message = `[VerificationGateway] the configured AstraSync API key was REJECTED at startup (${body.code ?? "api_key_invalid"}: ${body.message ?? "invalid key"}). Every inbound agent will be turned away until the key is rotated` + (body.remediation?.manageUrl ? ` at ${body.remediation.manageUrl}` : "") + `.`;
|
|
5045
|
+
if (strictInit) {
|
|
5046
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
5047
|
+
}
|
|
5048
|
+
console.error(message);
|
|
5049
|
+
} else if (selfCheck.ok) {
|
|
5050
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
5051
|
+
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
5052
|
+
console.warn(
|
|
5053
|
+
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
5054
|
+
);
|
|
5055
|
+
} else if (debug) {
|
|
5056
|
+
console.log("[VerificationGateway] API key self-check passed");
|
|
5057
|
+
}
|
|
5058
|
+
}
|
|
5059
|
+
}
|
|
5038
5060
|
} catch (err) {
|
|
5039
5061
|
if (strictInit) {
|
|
5040
5062
|
throw err;
|
|
@@ -5110,8 +5132,17 @@ function cacheResult(request2, result, configuredTtl, counterpartyId) {
|
|
|
5110
5132
|
function createGuidanceResponse(_config, reason, options = {}) {
|
|
5111
5133
|
const source = options.source ?? "no_credentials";
|
|
5112
5134
|
const isApiError = source === "api_error";
|
|
5135
|
+
const isMisconfig = source === "merchant_misconfig";
|
|
5113
5136
|
const urls = options.urls;
|
|
5114
|
-
const guidance =
|
|
5137
|
+
const guidance = isMisconfig ? {
|
|
5138
|
+
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or rotated). Your identity and the AstraSync platform are fine \u2014 contact the site operator. Retrying will not help.",
|
|
5139
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
5140
|
+
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
5141
|
+
steps: [
|
|
5142
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
|
|
5143
|
+
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
5144
|
+
]
|
|
5145
|
+
} : isApiError ? {
|
|
5115
5146
|
message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
|
|
5116
5147
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
5117
5148
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
@@ -5149,13 +5180,22 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
5149
5180
|
// partners (and their custom onDenied handlers) can branch on
|
|
5150
5181
|
// dimension. Without this, the synthesised stub was indistinguishable
|
|
5151
5182
|
// from a real policy deny.
|
|
5152
|
-
failures:
|
|
5183
|
+
failures: isMisconfig ? [
|
|
5184
|
+
{
|
|
5185
|
+
dimension: "verify_access.merchant_misconfigured",
|
|
5186
|
+
message: reason ?? "The integration API key was rejected by AstraSync",
|
|
5187
|
+
guidance: guidance.message
|
|
5188
|
+
}
|
|
5189
|
+
] : isApiError ? [
|
|
5153
5190
|
{
|
|
5154
5191
|
dimension: "verify_access.api_error",
|
|
5155
5192
|
message: reason ?? "Verification temporarily unavailable",
|
|
5156
5193
|
guidance: guidance.message
|
|
5157
5194
|
}
|
|
5158
5195
|
] : void 0,
|
|
5196
|
+
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
5197
|
+
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
5198
|
+
...isMisconfig && { misconfigured: true },
|
|
5159
5199
|
correlationId: options.correlationId,
|
|
5160
5200
|
attemptId: options.attemptId,
|
|
5161
5201
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
@@ -5210,7 +5250,8 @@ async function callVerifyAccessAPI(config, request2) {
|
|
|
5210
5250
|
const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
5211
5251
|
method: "POST",
|
|
5212
5252
|
headers,
|
|
5213
|
-
body: JSON.stringify(body)
|
|
5253
|
+
body: JSON.stringify(body),
|
|
5254
|
+
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
5214
5255
|
});
|
|
5215
5256
|
const data = await response.json();
|
|
5216
5257
|
if (response.status === 410) {
|
|
@@ -5234,6 +5275,17 @@ async function callVerifyAccessAPI(config, request2) {
|
|
|
5234
5275
|
};
|
|
5235
5276
|
}
|
|
5236
5277
|
if (!response.ok) {
|
|
5278
|
+
if (response.status === 401) {
|
|
5279
|
+
return {
|
|
5280
|
+
success: false,
|
|
5281
|
+
error: data.message || data.error || "Integration API key rejected",
|
|
5282
|
+
misconfig: true,
|
|
5283
|
+
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
5284
|
+
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
5285
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
5286
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
5287
|
+
};
|
|
5288
|
+
}
|
|
5237
5289
|
return {
|
|
5238
5290
|
success: false,
|
|
5239
5291
|
error: data.message || data.error || `API returned ${response.status}`,
|
|
@@ -5255,9 +5307,19 @@ async function verify(config, request2, options) {
|
|
|
5255
5307
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
5256
5308
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
5257
5309
|
if (mergedConfig.strictInit) {
|
|
5258
|
-
await performInitCheck(
|
|
5310
|
+
await performInitCheck(
|
|
5311
|
+
mergedConfig.apiBaseUrl,
|
|
5312
|
+
mergedConfig.debug,
|
|
5313
|
+
true,
|
|
5314
|
+
mergedConfig.apiKey
|
|
5315
|
+
);
|
|
5259
5316
|
} else {
|
|
5260
|
-
void performInitCheck(
|
|
5317
|
+
void performInitCheck(
|
|
5318
|
+
mergedConfig.apiBaseUrl,
|
|
5319
|
+
mergedConfig.debug,
|
|
5320
|
+
false,
|
|
5321
|
+
mergedConfig.apiKey
|
|
5322
|
+
);
|
|
5261
5323
|
}
|
|
5262
5324
|
}
|
|
5263
5325
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
@@ -5296,9 +5358,10 @@ async function verify(config, request2, options) {
|
|
|
5296
5358
|
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
5297
5359
|
if (!apiResponse.success) {
|
|
5298
5360
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
5299
|
-
source: "api_error",
|
|
5361
|
+
source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
|
|
5300
5362
|
correlationId: apiResponse.correlationId,
|
|
5301
5363
|
attemptId: apiResponse.attemptId,
|
|
5364
|
+
remediation: apiResponse.remediation,
|
|
5302
5365
|
urls
|
|
5303
5366
|
});
|
|
5304
5367
|
}
|