@astrasyncai/verification-gateway 5.17.2 → 5.18.1
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/CHANGELOG.md +1878 -0
- package/README.md +141 -7
- package/dist/adapters/express.d.mts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +30 -12
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +30 -12
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/kit-express.d.mts +63 -0
- package/dist/adapters/kit-express.d.ts +63 -0
- package/dist/adapters/kit-express.js +88 -0
- package/dist/adapters/kit-express.js.map +1 -0
- package/dist/adapters/kit-express.mjs +61 -0
- package/dist/adapters/kit-express.mjs.map +1 -0
- package/dist/adapters/mcp.d.mts +1 -1
- package/dist/adapters/mcp.d.ts +1 -1
- package/dist/adapters/mcp.js +1 -1
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +1 -1
- 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 +18 -8
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +18 -8
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +1 -1
- package/dist/adapters/sdk.d.ts +1 -1
- package/dist/adapters/sdk.js +1 -1
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +1 -1
- 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 +1 -1
- package/dist/bin/astrasync-codex-hook.js +1 -1
- package/dist/bin/astrasync-guard.js +330 -112
- package/dist/bin/astrasync.js +359 -113
- package/dist/browser/background.js +1 -1
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +1 -1
- 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 +1 -1
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +1 -1
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +1 -1
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +1 -1
- 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 +5 -4
- package/dist/edge-core/index.d.ts +5 -4
- package/dist/edge-core/index.js +18 -8
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +18 -8
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +1 -1
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +1 -1
- 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 +391 -13
- package/dist/index.d.ts +391 -13
- package/dist/index.js +766 -230
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +749 -222
- package/dist/index.mjs.map +1 -1
- package/dist/registration/index.d.mts +1 -1
- package/dist/registration/index.d.ts +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.d.mts +4 -3
- package/dist/transport/index.d.ts +4 -3
- 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-vNBvYD7Z.d.mts → types-3ObBpsnf.d.mts} +7 -0
- package/dist/{types-DA8LzAOB.d.ts → types-BoxZEYPS.d.ts} +7 -0
- package/dist/{types-DRb_plOh.d.mts → types-Cns4l8gX.d.mts} +17 -0
- package/dist/{types-DRb_plOh.d.ts → types-Cns4l8gX.d.ts} +17 -0
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +1 -1
- package/dist/verify.d.ts +1 -1
- package/dist/verify.js +1 -1
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +1 -1
- package/dist/verify.mjs.map +1 -1
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -575,7 +575,7 @@ Read `result.settlementOutcome.status` — never `success` alone:
|
|
|
575
575
|
|
|
576
576
|
| status | Meaning | Your action |
|
|
577
577
|
| ------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
578
|
-
| `pending_merchant` |
|
|
578
|
+
| `pending_merchant` | Order recorded — YOU settle it | Charge the `settlementToken` (card) or redeem the `settlement` voucher (stablecoin), then `reportSettlement()` |
|
|
579
579
|
| `settled` | Money moved (reported / webhook) | Fulfil / mark paid |
|
|
580
580
|
| `requires_approval` | Held for human step-up — not a failure | Record as pending; a re-drive follows approval |
|
|
581
581
|
| `failed` | Charge declined (`failureCode`) | Mark failed |
|
|
@@ -583,7 +583,7 @@ Read `result.settlementOutcome.status` — never `success` alone:
|
|
|
583
583
|
| `no_instrument` | Policy passed, no chargeable card on file | Terminal on autonomous; NON-terminal after approval — the human's approval survives; re-drive the same session once a card exists |
|
|
584
584
|
| _anything else_ | A status newer than your SDK | Treat as PENDING, never failed (open union, 5.5.0) |
|
|
585
585
|
|
|
586
|
-
**Every merchant settles (
|
|
586
|
+
**Every merchant settles (AstraSync never charges):** a purchase
|
|
587
587
|
grant records the order and returns `settlementOutcome: { status:
|
|
588
588
|
'pending_merchant', orderId }` with what you settle:
|
|
589
589
|
|
|
@@ -619,6 +619,124 @@ material (the bridge strips it from the agent plane). Shipping addresses
|
|
|
619
619
|
never transit AstraSync: take them agent → your fulfilment endpoint
|
|
620
620
|
directly, joined by `sessionId`.
|
|
621
621
|
|
|
622
|
+
## UCP & ACP checkout kits
|
|
623
|
+
|
|
624
|
+
`createUcpCheckoutKit()` (UCP 2026-08-25 REST) and `createAcpCheckoutKit()`
|
|
625
|
+
(ACP 2026-04-17) do the protocol work of a checkout endpoint; you supply the
|
|
626
|
+
catalog, settlement and fulfilment. Both are fetch-style
|
|
627
|
+
(`kit.handle(request) → Response`).
|
|
628
|
+
|
|
629
|
+
```ts
|
|
630
|
+
import {
|
|
631
|
+
createUcpCheckoutKit,
|
|
632
|
+
expressHandler,
|
|
633
|
+
RedisIdempotencyStore,
|
|
634
|
+
} from '@astrasyncai/verification-gateway';
|
|
635
|
+
|
|
636
|
+
const ucp = createUcpCheckoutKit({
|
|
637
|
+
profile: {
|
|
638
|
+
endpoint: 'https://shop.example/ucp/v1',
|
|
639
|
+
paymentHandlers: ['ai.astrasync.card_token'],
|
|
640
|
+
ap2Mandates: true,
|
|
641
|
+
orders: true, // dev.ucp.shopping.order: GET /orders/{id} + order webhooks
|
|
642
|
+
},
|
|
643
|
+
currency: 'USD',
|
|
644
|
+
catalog: async (id) => db.items.find(id),
|
|
645
|
+
verifyPurchase: (ctx) =>
|
|
646
|
+
client.confirmCheckout({
|
|
647
|
+
astraId: ctx.astraId,
|
|
648
|
+
attemptId: ctx.attemptId,
|
|
649
|
+
checkoutSessionId: ctx.checkoutSessionId,
|
|
650
|
+
checkoutJwt: ctx.checkoutJwt,
|
|
651
|
+
transactionValue: ctx.valueMajor,
|
|
652
|
+
currency: 'USD',
|
|
653
|
+
}),
|
|
654
|
+
settle: async ({ result }) => chargeWithYourProcessor(result), // settled | pending | failed
|
|
655
|
+
reportSettlement: (r) => client.reportSettlement(r),
|
|
656
|
+
fulfil: async ({ session }) => ({ id: await createOrder(session) }),
|
|
657
|
+
signingKey: { privateKey, kid: 'merchant-1' },
|
|
658
|
+
store: myCheckoutStore, // get / put / claim (+ findByOrderId)
|
|
659
|
+
idempotencyStore: new RedisIdempotencyStore(redis),
|
|
660
|
+
links: [
|
|
661
|
+
{ type: 'terms_of_service', url: 'https://shop.example/terms' },
|
|
662
|
+
{ type: 'privacy_policy', url: 'https://shop.example/privacy' },
|
|
663
|
+
],
|
|
664
|
+
permalinkBase: 'https://shop.example/orders',
|
|
665
|
+
webhook: {}, // URL from the platform profile; signed with signingKey
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
app.get('/.well-known/ucp', (_req, res) => res.json(ucp.profile));
|
|
669
|
+
app.use('/ucp/v1', express.raw({ type: '*/*' }), expressHandler(ucp));
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
- **Stores.** The defaults are in-memory (one process, lost on restart); the
|
|
673
|
+
kits warn when they run on them outside `NODE_ENV=test`. In production pass
|
|
674
|
+
`store` and `idempotencyStore` (`RedisIdempotencyStore`).
|
|
675
|
+
- **`claim(id, from, to)`** — an atomic compare-and-set of the session status
|
|
676
|
+
on your store (e.g. `UPDATE … SET status = $to WHERE id = $id AND status =
|
|
677
|
+
$from`). `complete` claims `complete_in_progress` before it verifies, so two
|
|
678
|
+
concurrent completes never both charge: the loser gets the session back with
|
|
679
|
+
a recoverable `checkout_in_progress` message (UCP) or `409
|
|
680
|
+
checkout_in_progress` (ACP). Without `claim` the kit warns once and the lock
|
|
681
|
+
is best-effort. `MemoryCheckoutStore` implements it.
|
|
682
|
+
- **Holds never settle.** Any step-up signal (`requiresStepUp`,
|
|
683
|
+
`requiresApproval`, `recommendation: 'step_up_required'`, a
|
|
684
|
+
`requires_approval` outcome, or a `stepUpApproval` that isn't `consumed`)
|
|
685
|
+
returns UCP `requires_escalation` with `continue_url` = the buyer's approval
|
|
686
|
+
page, or ACP `pending_approval`. After approval the platform completes again;
|
|
687
|
+
the redeemed approval comes back `status: 'consumed'` and the purchase
|
|
688
|
+
proceeds.
|
|
689
|
+
- **`kit.resolvePending(sessionId, { status, processorRef?, txHash?, chainId?, failureCode? })`**
|
|
690
|
+
— when `settle` returns `pending`, the session stays `complete_in_progress`
|
|
691
|
+
with no order. Call `resolvePending` from your processor's webhook:
|
|
692
|
+
`'settled'` reports the settlement, runs `fulfil` and completes the session
|
|
693
|
+
(sending the UCP order webhook); `'failed'` reports it and returns the
|
|
694
|
+
session to `ready_for_complete` / `ready_for_payment`. Calling it again is a
|
|
695
|
+
no-op. The stored result never contains the settlement token, voucher or
|
|
696
|
+
mandates.
|
|
697
|
+
- **One instrument (UCP).** `complete` needs exactly one
|
|
698
|
+
`payment.instruments[]` entry whose `handler_id` is one of your
|
|
699
|
+
`payment_handlers`; anything else is `payment_failed`.
|
|
700
|
+
- **`links`** (UCP) — `terms_of_service`, `privacy_policy`, `refund_policy`,
|
|
701
|
+
`shipping_policy`, `faq` (`{ type, url, title? }`), returned on every
|
|
702
|
+
checkout and covered by `ap2.merchant_authorization`. A GET returns the
|
|
703
|
+
stored authorization; it never re-signs or writes.
|
|
704
|
+
- **Agent binding (UCP).** After `verifyPurchase`, the `UCP-Agent` profile is
|
|
705
|
+
checked against the verified agent's `protocolIdentities.ucpProfile`
|
|
706
|
+
(override with `resolveIdentities(req, result)`); a mismatch is
|
|
707
|
+
`ucp_agent_mismatch` and nothing settles. `ucpAgentBinding: 'registered'`
|
|
708
|
+
(default) lets agents with no registered profile through (e.g. the AstraSync
|
|
709
|
+
bridge's own profile); `'strict'` refuses them; `'off'` skips the check.
|
|
710
|
+
- **Caller scope.** Sessions and idempotency keys belong to the caller: the
|
|
711
|
+
verified ASTRA-id (`ctx.callerId` from `expressHandler`, or your
|
|
712
|
+
`resolveCallerId(req)`), else the `Authorization` header, else `X-Astra-Id`.
|
|
713
|
+
UCP falls back to the platform profile; ACP refuses a request with none
|
|
714
|
+
(401). Another caller gets 404, and never another caller's replay.
|
|
715
|
+
- **`expressHandler(kit, { callerId? })`** (also `/kit-express`) — mounts a
|
|
716
|
+
kit on Express. Give it the raw body (`express.raw()` on the kit's routes,
|
|
717
|
+
or `req.rawBody` from your JSON parser's `verify` hook): signatures and
|
|
718
|
+
idempotency fingerprints are computed over the exact bytes. When the
|
|
719
|
+
AstraSync middleware ran first, the verified ASTRA-id scopes the session.
|
|
720
|
+
- **UCP orders.** `buildUcpOrder(session)` is the `dev.ucp.shopping.order`
|
|
721
|
+
entity; `GET /orders/{id}` serves it; `webhook` sends it, signed, when the
|
|
722
|
+
order is created, and `kit.sendOrderWebhook(sessionId)` sends it again after
|
|
723
|
+
you update it.
|
|
724
|
+
- **ACP.** An `API-Version` other than `2026-04-17` is `400
|
|
725
|
+
unsupported_api_version` with `supported_versions`; `Idempotency-Key` and
|
|
726
|
+
`Request-Id` are echoed; `order.line_items` mirrors the session;
|
|
727
|
+
`permalinkBase` fills `permalink_url`. `buildAcpWellKnown({ endpoint,
|
|
728
|
+
paymentHandlers })` is a discovery document to serve at
|
|
729
|
+
`/.well-known/acp.json`.
|
|
730
|
+
- Canceling a completed or canceled checkout is `405` on both.
|
|
731
|
+
|
|
732
|
+
### Unmatched routes (Express)
|
|
733
|
+
|
|
734
|
+
A request no configured route matches passes through by default
|
|
735
|
+
(`defaultRoutePolicy: 'pass'`). With `evaluateAlwaysIfCredentialed` and an
|
|
736
|
+
`X-Astra-Id`, or with `defaultRoutePolicy: 'observe'` and any AstraSync
|
|
737
|
+
credential, it's evaluated in observe mode: `req.agentVerification` is set and
|
|
738
|
+
the call is recorded, but the request always reaches your handler.
|
|
739
|
+
|
|
622
740
|
## Settlement Artifacts
|
|
623
741
|
|
|
624
742
|
On a clean merchant-mediated grant where the owner has a verified payment instrument, verify-access returns a `settlement` object (wire format **v2**, versioned via the `ver: 2` claim — verify/redeem reject other versions):
|
|
@@ -660,11 +778,11 @@ interface FiatSettlementBinding {
|
|
|
660
778
|
|
|
661
779
|
### Voucher lifecycle (server-to-server)
|
|
662
780
|
|
|
663
|
-
| Endpoint | Purpose
|
|
664
|
-
| ------------------------------------------------ |
|
|
665
|
-
| `POST /api/wallets/voucher/verify` | Verify signature/issuer and return the decoded payload — proves authenticity only, no spend
|
|
666
|
-
| `POST /api/wallets/voucher/redeem` | Atomic single-use spend: first caller gets `200 redeemed` (plus `order: { status: 'redeemed' }` when the voucher funds a recorded order —
|
|
667
|
-
| `GET /api/wallets/voucher/.well-known/jwks.json` | Public JWKS for offline signature verification
|
|
781
|
+
| Endpoint | Purpose |
|
|
782
|
+
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
783
|
+
| `POST /api/wallets/voucher/verify` | Verify signature/issuer and return the decoded payload — proves authenticity only, no spend |
|
|
784
|
+
| `POST /api/wallets/voucher/redeem` | Atomic single-use spend: first caller gets `200 redeemed` (plus `order: { status: 'redeemed' }` when the voucher funds a recorded order — no charge happens here) , replays get `409 already_redeemed` (with first-redeemer forensics), revoked vouchers get `409 revoked` |
|
|
785
|
+
| `GET /api/wallets/voucher/.well-known/jwks.json` | Public JWKS for offline signature verification |
|
|
668
786
|
|
|
669
787
|
Redeem accepts optional `expectedAmountMinor` / `expectedCurrency` — mismatches are rejected (`400 amount_mismatch` / `currency_mismatch`) **before** the voucher is spent, so a mismatch never burns the voucher. Vouchers carry `aud` = your merchant id; declare `merchantId` on verify/redeem to have the audience check enforced (standard JWT libraries give you the same check free on offline verification).
|
|
670
788
|
|
|
@@ -889,6 +1007,18 @@ answered by the checkpoint; the agent needs no `apiEndpoint` of its own.
|
|
|
889
1007
|
|
|
890
1008
|
Newest first. Full detail for every release is in [CHANGELOG.md](./CHANGELOG.md).
|
|
891
1009
|
|
|
1010
|
+
### v5.18.0 — checkout kit fixes, orders, Express mounting, MPP interop
|
|
1011
|
+
|
|
1012
|
+
- UCP / ACP kits: holds never settle; `resolvePending()` finishes a pending settlement; `complete` claims the session (store `claim`) so concurrent completes can't both charge; sessions and idempotency keys are scoped to the caller.
|
|
1013
|
+
- UCP: exactly one payment instrument; `UCP-Agent` bound to the verified agent; `links` in the signed checkout; GETs don't re-sign; order capability (`GET /orders/{id}`, `buildUcpOrder`, signed order webhooks).
|
|
1014
|
+
- ACP: `unsupported_api_version`, echoed `Idempotency-Key` / `Request-Id`, 405 on canceling a finished session, order line items and `permalink_url`, `buildAcpWellKnown()`.
|
|
1015
|
+
- `expressHandler(kit)` mounts a kit on Express with the raw body kept; Express `defaultRoutePolicy` and observe-mode evaluation of unmatched routes for credentialed callers.
|
|
1016
|
+
- MPP challenge ids now match mppx; `buildMpp402Response()`; `verifyMppChallenge` checks the body digest and can accept each challenge once.
|
|
1017
|
+
|
|
1018
|
+
### v5.17.2 — guard browse says where to approve
|
|
1019
|
+
|
|
1020
|
+
- `astrasync guard browse` prints the approval link while it waits for the owner's passkey.
|
|
1021
|
+
|
|
892
1022
|
### v5.17.1 — one approval for a route that holds its own
|
|
893
1023
|
|
|
894
1024
|
- `approvalHeldByRoute` (Express): a route that holds its own owner approval receives an approval-only result instead of a refusal, and verify-access creates no approval — the owner approves once.
|
|
@@ -909,6 +1039,10 @@ Newest first. Full detail for every release is in [CHANGELOG.md](./CHANGELOG.md)
|
|
|
909
1039
|
registers each call while it is in flight; otherwise call
|
|
910
1040
|
`registerPending()` / `removePending()` around each interaction.
|
|
911
1041
|
|
|
1042
|
+
### v5.15.0 — agentic commerce protocols
|
|
1043
|
+
|
|
1044
|
+
- AP2 v0.2 mandates, UCP (profile, negotiation, signatures, webhooks) and ACP checkout kits, KYAPay token verification, RFC 9421 request signing, request idempotency, and merchant helpers for x402 v2 and MPP.
|
|
1045
|
+
|
|
912
1046
|
### v4.1.0 — Trusted Agent Gateway naming + MCP metadata capture
|
|
913
1047
|
|
|
914
1048
|
- The Next.js unverified-agent overlay is now the **verification interstitial**: `showInterstitial` option, `VerificationInterstitial` / `useVerificationInterstitial` / `VerificationInterstitialProps`. The old `showCommerceShield` / `CommerceShield` / `useCommerceShield` / `CommerceShieldProps` names keep working as deprecated aliases until the next major (`showInterstitial` wins when both options are set).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequestHandler, Request } from 'express';
|
|
2
|
-
import { d as VerificationResult, E as ExpressMiddlewareOptions, a as AstraSyncCredentials } from '../types-
|
|
2
|
+
import { d as VerificationResult, E as ExpressMiddlewareOptions, a as AstraSyncCredentials } from '../types-Cns4l8gX.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* AstraSync Universal Verification Gateway - Express Middleware
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequestHandler, Request } from 'express';
|
|
2
|
-
import { d as VerificationResult, E as ExpressMiddlewareOptions, a as AstraSyncCredentials } from '../types-
|
|
2
|
+
import { d as VerificationResult, E as ExpressMiddlewareOptions, a as AstraSyncCredentials } from '../types-Cns4l8gX.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* AstraSync Universal Verification Gateway - Express Middleware
|
package/dist/adapters/express.js
CHANGED
|
@@ -316,6 +316,23 @@ function detectCommerce(req, host) {
|
|
|
316
316
|
}
|
|
317
317
|
const signature = headerValue(req, "signature");
|
|
318
318
|
const signatureInput = headerValue(req, "signature-input");
|
|
319
|
+
if (/\/checkout[-_]sessions(\/|$)/.test(req.uri) && headerValue(req, "ucp-agent")) {
|
|
320
|
+
const signed = Boolean(signature && signatureInput);
|
|
321
|
+
return {
|
|
322
|
+
protocol: "ucp",
|
|
323
|
+
artifacts: {
|
|
324
|
+
ucpRequest: { method, url, ...jsonBody && { body: jsonBody } },
|
|
325
|
+
...signed && {
|
|
326
|
+
rfc9421: { headers, method, url, ...req.bodyText && { body: req.bodyText } }
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
evidence: {
|
|
330
|
+
path: req.uri,
|
|
331
|
+
...signed && { keyid: signatureInput.match(/keyid="([^"]+)"/)?.[1] },
|
|
332
|
+
...truncated
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
}
|
|
319
336
|
if (signature && signatureInput) {
|
|
320
337
|
const signatureAgent = headerValue(req, "signature-agent");
|
|
321
338
|
const registryHint = headerValue(req, "x-agent-registry");
|
|
@@ -350,13 +367,6 @@ function detectCommerce(req, host) {
|
|
|
350
367
|
evidence: { hasTimestamp: Boolean(acpTimestamp), ...truncated }
|
|
351
368
|
};
|
|
352
369
|
}
|
|
353
|
-
if (/\/checkout[-_]sessions(\/|$)/.test(req.uri) && headerValue(req, "ucp-agent")) {
|
|
354
|
-
return {
|
|
355
|
-
protocol: "ucp",
|
|
356
|
-
artifacts: { ucpRequest: { method, url, ...jsonBody && { body: jsonBody } } },
|
|
357
|
-
evidence: { path: req.uri, ...truncated }
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
370
|
if (jsonBody) {
|
|
361
371
|
const intent = jsonBody.intent_mandate ?? jsonBody.intentMandate;
|
|
362
372
|
const cart = jsonBody.cart_mandate ?? jsonBody.cartMandate;
|
|
@@ -469,7 +479,7 @@ function routePolicyOf(route) {
|
|
|
469
479
|
}
|
|
470
480
|
|
|
471
481
|
// src/version.ts
|
|
472
|
-
var SDK_VERSION = "5.
|
|
482
|
+
var SDK_VERSION = "5.18.1";
|
|
473
483
|
|
|
474
484
|
// src/http.ts
|
|
475
485
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -2361,6 +2371,7 @@ function createMiddleware(options) {
|
|
|
2361
2371
|
anonymousBeacon = true,
|
|
2362
2372
|
trustVerifiedHop = false,
|
|
2363
2373
|
verifiedHopMaxAgeMs,
|
|
2374
|
+
defaultRoutePolicy = "pass",
|
|
2364
2375
|
...config
|
|
2365
2376
|
} = options;
|
|
2366
2377
|
if (config.apiBaseUrl) {
|
|
@@ -2426,12 +2437,15 @@ function createMiddleware(options) {
|
|
|
2426
2437
|
});
|
|
2427
2438
|
}
|
|
2428
2439
|
const correlationId = req.headers["x-request-id"] || req.headers["x-correlation-id"];
|
|
2429
|
-
const
|
|
2440
|
+
const matchedRoute = findRouteConfig(cachedRoutes, req.path, req.method, {
|
|
2430
2441
|
caseInsensitive: caseInsensitiveRouteMatch,
|
|
2431
2442
|
logShadowDivergence: true,
|
|
2432
2443
|
correlationId
|
|
2433
2444
|
});
|
|
2434
|
-
|
|
2445
|
+
const credentials = customExtractCredentials ? customExtractCredentials(req) : defaultExtractCredentials(req);
|
|
2446
|
+
const credentialed = Boolean(credentials.astraId || credentials.apiKey || credentials.jwt);
|
|
2447
|
+
const observeUnmatched = !matchedRoute && (config.evaluateAlwaysIfCredentialed === true && Boolean(credentials.astraId) || defaultRoutePolicy === "observe" && credentialed);
|
|
2448
|
+
if (!matchedRoute && !observeUnmatched) {
|
|
2435
2449
|
if (config.setPassThroughHeader) {
|
|
2436
2450
|
res.setHeader("X-Astra-Gateway-Mode", "unenforced");
|
|
2437
2451
|
res.setHeader(
|
|
@@ -2442,10 +2456,14 @@ function createMiddleware(options) {
|
|
|
2442
2456
|
beaconPassThrough?.(req);
|
|
2443
2457
|
return next();
|
|
2444
2458
|
}
|
|
2459
|
+
const routeConfig = matchedRoute ?? {
|
|
2460
|
+
pattern: req.path,
|
|
2461
|
+
method: req.method,
|
|
2462
|
+
observe: true
|
|
2463
|
+
};
|
|
2445
2464
|
const wellKnownUrls = config.apiBaseUrl ? await getWellKnownUrls(config.apiBaseUrl).catch(() => void 0) : void 0;
|
|
2446
|
-
const credentials = customExtractCredentials ? customExtractCredentials(req) : defaultExtractCredentials(req);
|
|
2447
2465
|
const shouldEnforce = !routeConfig.observe;
|
|
2448
|
-
if (routeConfig.observe && (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)) {
|
|
2466
|
+
if (routeConfig.observe && !observeUnmatched && (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)) {
|
|
2449
2467
|
if (config.setPassThroughHeader) {
|
|
2450
2468
|
res.setHeader("X-Astra-Gateway-Mode", "unenforced");
|
|
2451
2469
|
res.setHeader("X-Astra-Gateway-Reason", "route-observe");
|