@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/adapters/sdk.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as TrustLevel, S as SDKOptions, d as VerificationResult, c as VerificationRequest } from '../types-
|
|
1
|
+
import { T as TrustLevel, S as SDKOptions, d as VerificationResult, c as VerificationRequest } from '../types-BCkwBA84.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* AstraSync Universal Verification Gateway — Trust Level helpers.
|
|
@@ -101,6 +101,12 @@ declare class VerificationGatewayClient {
|
|
|
101
101
|
* fulfil against it only once the order is settled / pending_merchant. An
|
|
102
102
|
* explicit `buyerEmail` (here or on the bridge handoff body) wins over the
|
|
103
103
|
* account default.
|
|
104
|
+
*
|
|
105
|
+
* 5.12.0 approval binding: pass the bridge handoff body's `attemptId` (and
|
|
106
|
+
* the same `checkoutSessionId`) so a step-up approval minted for this cart
|
|
107
|
+
* is matched to — and only to — this confirm. A held cart's approval is
|
|
108
|
+
* bound to its checkout session and exact value; a confirm for any other
|
|
109
|
+
* cart is held for its own approval.
|
|
104
110
|
*/
|
|
105
111
|
confirmCheckout(options: {
|
|
106
112
|
astraId?: string;
|
|
@@ -112,6 +118,8 @@ declare class VerificationGatewayClient {
|
|
|
112
118
|
currency?: string;
|
|
113
119
|
checkoutSessionId?: string;
|
|
114
120
|
checkoutItems?: VerificationRequest['checkoutItems'];
|
|
121
|
+
/** 5.12.0: the `att_…` attempt-chain id from the bridge handoff body. */
|
|
122
|
+
attemptId?: string;
|
|
115
123
|
/** 5.6.0: alternate receipt/delivery email (transit-only) — omit to let
|
|
116
124
|
* the platform default `fulfilment.email` to the buyer's account email. */
|
|
117
125
|
buyerEmail?: string;
|
package/dist/adapters/sdk.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as TrustLevel, S as SDKOptions, d as VerificationResult, c as VerificationRequest } from '../types-
|
|
1
|
+
import { T as TrustLevel, S as SDKOptions, d as VerificationResult, c as VerificationRequest } from '../types-BCkwBA84.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* AstraSync Universal Verification Gateway — Trust Level helpers.
|
|
@@ -101,6 +101,12 @@ declare class VerificationGatewayClient {
|
|
|
101
101
|
* fulfil against it only once the order is settled / pending_merchant. An
|
|
102
102
|
* explicit `buyerEmail` (here or on the bridge handoff body) wins over the
|
|
103
103
|
* account default.
|
|
104
|
+
*
|
|
105
|
+
* 5.12.0 approval binding: pass the bridge handoff body's `attemptId` (and
|
|
106
|
+
* the same `checkoutSessionId`) so a step-up approval minted for this cart
|
|
107
|
+
* is matched to — and only to — this confirm. A held cart's approval is
|
|
108
|
+
* bound to its checkout session and exact value; a confirm for any other
|
|
109
|
+
* cart is held for its own approval.
|
|
104
110
|
*/
|
|
105
111
|
confirmCheckout(options: {
|
|
106
112
|
astraId?: string;
|
|
@@ -112,6 +118,8 @@ declare class VerificationGatewayClient {
|
|
|
112
118
|
currency?: string;
|
|
113
119
|
checkoutSessionId?: string;
|
|
114
120
|
checkoutItems?: VerificationRequest['checkoutItems'];
|
|
121
|
+
/** 5.12.0: the `att_…` attempt-chain id from the bridge handoff body. */
|
|
122
|
+
attemptId?: string;
|
|
115
123
|
/** 5.6.0: alternate receipt/delivery email (transit-only) — omit to let
|
|
116
124
|
* the platform default `fulfilment.email` to the buyer's account email. */
|
|
117
125
|
buyerEmail?: string;
|
package/dist/adapters/sdk.js
CHANGED
|
@@ -28,7 +28,7 @@ __export(sdk_exports, {
|
|
|
28
28
|
module.exports = __toCommonJS(sdk_exports);
|
|
29
29
|
|
|
30
30
|
// src/version.ts
|
|
31
|
-
var SDK_VERSION = "5.
|
|
31
|
+
var SDK_VERSION = "5.13.0";
|
|
32
32
|
|
|
33
33
|
// src/http.ts
|
|
34
34
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -63,6 +63,29 @@ function getCachedWellKnownUrls(apiBaseUrl) {
|
|
|
63
63
|
return cache.get(apiBaseUrl)?.data;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
// src/failure-posture.ts
|
|
67
|
+
var DEFAULT_UNAVAILABLE_RETRY_AFTER_S = 30;
|
|
68
|
+
var REJECTED_IDENTITY_DIMENSIONS = /* @__PURE__ */ new Set([
|
|
69
|
+
"identity.invalid_agent_id",
|
|
70
|
+
"identity.unknown_agent",
|
|
71
|
+
"agent.lookup"
|
|
72
|
+
]);
|
|
73
|
+
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.";
|
|
74
|
+
var UNAVAILABLE_DIMENSIONS = /* @__PURE__ */ new Set([
|
|
75
|
+
"verify_access.api_error",
|
|
76
|
+
"middleware.internal_error"
|
|
77
|
+
]);
|
|
78
|
+
function isVerificationUnavailable(result) {
|
|
79
|
+
if (result.misconfigured) return false;
|
|
80
|
+
return (result.failures ?? []).some((f) => UNAVAILABLE_DIMENSIONS.has(f.dimension));
|
|
81
|
+
}
|
|
82
|
+
function unavailableRetryAfterSeconds(result) {
|
|
83
|
+
if (typeof result.retryAfterMs === "number" && Number.isFinite(result.retryAfterMs)) {
|
|
84
|
+
return Math.max(1, Math.ceil(result.retryAfterMs / 1e3));
|
|
85
|
+
}
|
|
86
|
+
return DEFAULT_UNAVAILABLE_RETRY_AFTER_S;
|
|
87
|
+
}
|
|
88
|
+
|
|
66
89
|
// src/verify.ts
|
|
67
90
|
var DEFAULT_CONFIG = {
|
|
68
91
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
@@ -75,7 +98,7 @@ var DEFAULT_CONFIG = {
|
|
|
75
98
|
};
|
|
76
99
|
var initCheckPerformed = false;
|
|
77
100
|
var deprecationWarningShown = false;
|
|
78
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
101
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey, counterparty) {
|
|
79
102
|
initCheckPerformed = true;
|
|
80
103
|
try {
|
|
81
104
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -93,7 +116,8 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
93
116
|
);
|
|
94
117
|
}
|
|
95
118
|
if (apiKey) {
|
|
96
|
-
const
|
|
119
|
+
const q = counterparty?.id ? `?counterpartyId=${encodeURIComponent(counterparty.id)}` : counterparty?.url ? `?counterpartyUrl=${encodeURIComponent(counterparty.url)}` : "";
|
|
120
|
+
const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check${q}`, {
|
|
97
121
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
98
122
|
});
|
|
99
123
|
if (selfCheck.status === 401) {
|
|
@@ -105,6 +129,13 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
105
129
|
console.error(message);
|
|
106
130
|
} else if (selfCheck.ok) {
|
|
107
131
|
const body = await selfCheck.json().catch(() => ({}));
|
|
132
|
+
if (body.counterparty && body.counterparty.canVerify === false) {
|
|
133
|
+
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.`;
|
|
134
|
+
if (strictInit) {
|
|
135
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
136
|
+
}
|
|
137
|
+
console.error(message);
|
|
138
|
+
}
|
|
108
139
|
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
109
140
|
console.warn(
|
|
110
141
|
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
@@ -212,11 +243,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
212
243
|
const isMisconfig = source === "merchant_misconfig";
|
|
213
244
|
const urls = options.urls;
|
|
214
245
|
const guidance = isMisconfig ? {
|
|
215
|
-
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or
|
|
246
|
+
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.",
|
|
216
247
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
217
248
|
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
218
249
|
steps: [
|
|
219
|
-
"Report the failure to the site operator \u2014 their AstraSync API key needs
|
|
250
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs replacing",
|
|
220
251
|
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
221
252
|
]
|
|
222
253
|
} : isApiError ? {
|
|
@@ -277,11 +308,44 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
277
308
|
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
278
309
|
// deterministic and intentionally NOT marked retryable.
|
|
279
310
|
...isApiError && { retryable: true },
|
|
311
|
+
...options.httpStatus !== void 0 && { httpStatus: options.httpStatus },
|
|
312
|
+
...options.retryAfterMs !== void 0 && { retryAfterMs: options.retryAfterMs },
|
|
280
313
|
correlationId: options.correlationId,
|
|
281
314
|
attemptId: options.attemptId,
|
|
282
315
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
283
316
|
};
|
|
284
317
|
}
|
|
318
|
+
async function readJsonSafe(response) {
|
|
319
|
+
try {
|
|
320
|
+
const parsed = await response.json();
|
|
321
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
322
|
+
} catch {
|
|
323
|
+
return {};
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
function rejectedIdentityGuidance(failures) {
|
|
327
|
+
const f = failures?.find((x) => REJECTED_IDENTITY_DIMENSIONS.has(x.dimension));
|
|
328
|
+
if (!f) return void 0;
|
|
329
|
+
if (f.dimension === "agent.lookup") {
|
|
330
|
+
return `The presented agent identifier is not registered with AstraSync. ${UNKNOWN_AGENT_GUIDANCE}`;
|
|
331
|
+
}
|
|
332
|
+
return f.guidance ? `${f.message} ${f.guidance}` : f.message;
|
|
333
|
+
}
|
|
334
|
+
var MAX_RETRY_AFTER_MS = 15 * 60 * 1e3;
|
|
335
|
+
function parseRetryAfterMs(response) {
|
|
336
|
+
const raw = response.headers?.get?.("retry-after");
|
|
337
|
+
if (!raw) return void 0;
|
|
338
|
+
const trimmed = raw.trim();
|
|
339
|
+
let ms;
|
|
340
|
+
if (/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
341
|
+
ms = Number(trimmed) * 1e3;
|
|
342
|
+
} else {
|
|
343
|
+
const at = Date.parse(trimmed);
|
|
344
|
+
if (Number.isNaN(at)) return void 0;
|
|
345
|
+
ms = at - Date.now();
|
|
346
|
+
}
|
|
347
|
+
return Math.min(MAX_RETRY_AFTER_MS, Math.max(0, Math.round(ms)));
|
|
348
|
+
}
|
|
285
349
|
async function callVerifyAccessAPI(config, request) {
|
|
286
350
|
const { credentials, ...requestData } = request;
|
|
287
351
|
const body = {
|
|
@@ -338,7 +402,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
338
402
|
body: JSON.stringify(body),
|
|
339
403
|
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
340
404
|
});
|
|
341
|
-
const data = await response
|
|
405
|
+
const data = await readJsonSafe(response);
|
|
406
|
+
const retryAfterMs = parseRetryAfterMs(response);
|
|
342
407
|
if (response.status === 410) {
|
|
343
408
|
return {
|
|
344
409
|
success: true,
|
|
@@ -376,13 +441,31 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
376
441
|
}
|
|
377
442
|
};
|
|
378
443
|
}
|
|
444
|
+
if (response.status === 404 && credentials.astraId && (data?.error === "AGENT_NOT_FOUND" || typeof data?.message === "string" && /agent/i.test(data.message))) {
|
|
445
|
+
return {
|
|
446
|
+
success: true,
|
|
447
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
448
|
+
access: {
|
|
449
|
+
allowed: false,
|
|
450
|
+
reason: "unknown_agent",
|
|
451
|
+
failures: [
|
|
452
|
+
{
|
|
453
|
+
dimension: "identity.unknown_agent",
|
|
454
|
+
message: "The presented agent identifier is not registered with AstraSync.",
|
|
455
|
+
guidance: UNKNOWN_AGENT_GUIDANCE
|
|
456
|
+
}
|
|
457
|
+
]
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
}
|
|
379
461
|
if (!response.ok) {
|
|
380
|
-
|
|
462
|
+
const keyMismatch = response.status === 403 && data?.error === "COUNTERPARTY_KEY_MISMATCH";
|
|
463
|
+
if (response.status === 401 || keyMismatch) {
|
|
381
464
|
return {
|
|
382
465
|
success: false,
|
|
383
466
|
error: data.message || data.error || "Integration API key rejected",
|
|
384
467
|
misconfig: true,
|
|
385
|
-
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
468
|
+
misconfigCode: keyMismatch ? "counterparty_key_mismatch" : typeof data?.code === "string" ? data.code : void 0,
|
|
386
469
|
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
387
470
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
388
471
|
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
@@ -390,9 +473,11 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
390
473
|
}
|
|
391
474
|
return {
|
|
392
475
|
success: false,
|
|
393
|
-
error: data.message || data.error || `API returned ${response.status}`,
|
|
476
|
+
error: typeof data?.message === "string" && data.message || typeof data?.error === "string" && data.error || `API returned ${response.status}`,
|
|
394
477
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
395
|
-
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
478
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
479
|
+
httpStatus: response.status,
|
|
480
|
+
...retryAfterMs !== void 0 && { retryAfterMs }
|
|
396
481
|
};
|
|
397
482
|
}
|
|
398
483
|
return data;
|
|
@@ -413,14 +498,22 @@ async function verify(config, request, options) {
|
|
|
413
498
|
mergedConfig.apiBaseUrl,
|
|
414
499
|
mergedConfig.debug,
|
|
415
500
|
true,
|
|
416
|
-
mergedConfig.apiKey
|
|
501
|
+
mergedConfig.apiKey,
|
|
502
|
+
{
|
|
503
|
+
id: mergedConfig.counterpartyId,
|
|
504
|
+
url: mergedConfig.counterpartyUrl ?? request.counterpartyUrl
|
|
505
|
+
}
|
|
417
506
|
);
|
|
418
507
|
} else {
|
|
419
508
|
void performInitCheck(
|
|
420
509
|
mergedConfig.apiBaseUrl,
|
|
421
510
|
mergedConfig.debug,
|
|
422
511
|
false,
|
|
423
|
-
mergedConfig.apiKey
|
|
512
|
+
mergedConfig.apiKey,
|
|
513
|
+
{
|
|
514
|
+
id: mergedConfig.counterpartyId,
|
|
515
|
+
url: mergedConfig.counterpartyUrl ?? request.counterpartyUrl
|
|
516
|
+
}
|
|
424
517
|
);
|
|
425
518
|
}
|
|
426
519
|
}
|
|
@@ -464,12 +557,14 @@ async function verify(config, request, options) {
|
|
|
464
557
|
correlationId: apiResponse.correlationId,
|
|
465
558
|
attemptId: apiResponse.attemptId,
|
|
466
559
|
remediation: apiResponse.remediation,
|
|
560
|
+
httpStatus: apiResponse.httpStatus,
|
|
561
|
+
retryAfterMs: apiResponse.retryAfterMs,
|
|
467
562
|
urls
|
|
468
563
|
});
|
|
469
564
|
}
|
|
470
565
|
if (!apiResponse.access?.allowed) {
|
|
471
566
|
const aggregatedFailures = apiResponse.access?.failures;
|
|
472
|
-
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true;
|
|
567
|
+
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true && !aggregatedFailures?.some((f) => REJECTED_IDENTITY_DIMENSIONS.has(f.dimension));
|
|
473
568
|
const result2 = {
|
|
474
569
|
identityVerified: idVerifiedFromBackend,
|
|
475
570
|
policyAllowed: false,
|
|
@@ -481,7 +576,10 @@ async function verify(config, request, options) {
|
|
|
481
576
|
requiresStepUp: apiResponse.access?.requiresStepUp,
|
|
482
577
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
483
578
|
guidance: {
|
|
484
|
-
|
|
579
|
+
// 5.12.0: a presented-but-rejected id (malformed / unknown) carries
|
|
580
|
+
// actionable registration guidance on its failure — surface it
|
|
581
|
+
// instead of the bare machine reason ('unknown_agent').
|
|
582
|
+
message: rejectedIdentityGuidance(aggregatedFailures) ?? (apiResponse.access?.reason || "Access denied by PDLSS policy"),
|
|
485
583
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
486
584
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
487
585
|
// 5.1.0: anonymous callers land on this branch — steer MCP-hosted
|
|
@@ -581,7 +679,7 @@ async function verify(config, request, options) {
|
|
|
581
679
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
582
680
|
documentationUrl: urls?.documentationUrl ?? ""
|
|
583
681
|
};
|
|
584
|
-
} else if (result.recommendation === "step_up_required") {
|
|
682
|
+
} else if (result.recommendation === "step_up_required" && result.identityVerified) {
|
|
585
683
|
result.requiresStepUp = true;
|
|
586
684
|
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
|
|
587
685
|
}
|
|
@@ -599,7 +697,11 @@ async function quickVerify(config, credentials) {
|
|
|
599
697
|
return {
|
|
600
698
|
identityVerified: result.identityVerified,
|
|
601
699
|
policyAllowed: result.policyAllowed,
|
|
602
|
-
reason: result.denialReasons?.[0]
|
|
700
|
+
reason: result.denialReasons?.[0],
|
|
701
|
+
...isVerificationUnavailable(result) && {
|
|
702
|
+
unavailable: true,
|
|
703
|
+
retryAfterMs: unavailableRetryAfterSeconds(result) * 1e3
|
|
704
|
+
}
|
|
603
705
|
};
|
|
604
706
|
}
|
|
605
707
|
|
|
@@ -685,6 +787,12 @@ var VerificationGatewayClient = class {
|
|
|
685
787
|
* fulfil against it only once the order is settled / pending_merchant. An
|
|
686
788
|
* explicit `buyerEmail` (here or on the bridge handoff body) wins over the
|
|
687
789
|
* account default.
|
|
790
|
+
*
|
|
791
|
+
* 5.12.0 approval binding: pass the bridge handoff body's `attemptId` (and
|
|
792
|
+
* the same `checkoutSessionId`) so a step-up approval minted for this cart
|
|
793
|
+
* is matched to — and only to — this confirm. A held cart's approval is
|
|
794
|
+
* bound to its checkout session and exact value; a confirm for any other
|
|
795
|
+
* cart is held for its own approval.
|
|
688
796
|
*/
|
|
689
797
|
async confirmCheckout(options) {
|
|
690
798
|
const credentials = {
|
|
@@ -704,6 +812,7 @@ var VerificationGatewayClient = class {
|
|
|
704
812
|
commercePhase: "confirm",
|
|
705
813
|
checkoutSessionId: options.checkoutSessionId,
|
|
706
814
|
checkoutItems: options.checkoutItems,
|
|
815
|
+
...options.attemptId && { attemptId: options.attemptId },
|
|
707
816
|
buyerEmail: options.buyerEmail,
|
|
708
817
|
counterpartyUrl: options.counterpartyUrl,
|
|
709
818
|
counterpartyType: options.counterpartyType
|