@asteby/storefront-react 0.26.0 → 0.28.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.
Files changed (38) hide show
  1. package/README.md +7 -2
  2. package/dist/account-server.cjs +533 -83
  3. package/dist/account-server.cjs.map +1 -1
  4. package/dist/account-server.d.cts +13 -2
  5. package/dist/account-server.d.ts +13 -2
  6. package/dist/account-server.js +23 -6
  7. package/dist/account-server.js.map +1 -1
  8. package/dist/account.cjs +572 -96
  9. package/dist/account.cjs.map +1 -1
  10. package/dist/account.d.cts +82 -45
  11. package/dist/account.d.ts +82 -45
  12. package/dist/account.js +53 -14
  13. package/dist/account.js.map +1 -1
  14. package/dist/checkout.cjs +114 -38
  15. package/dist/checkout.cjs.map +1 -1
  16. package/dist/checkout.d.cts +24 -1
  17. package/dist/checkout.d.ts +24 -1
  18. package/dist/checkout.js +114 -38
  19. package/dist/checkout.js.map +1 -1
  20. package/dist/chunk-BXKV2KWZ.js +291 -0
  21. package/dist/chunk-BXKV2KWZ.js.map +1 -0
  22. package/dist/chunk-LIUEQENV.js +156 -0
  23. package/dist/chunk-LIUEQENV.js.map +1 -0
  24. package/dist/fiscal-server.cjs +27 -2
  25. package/dist/fiscal-server.cjs.map +1 -1
  26. package/dist/fiscal-server.d.cts +10 -1
  27. package/dist/fiscal-server.d.ts +10 -1
  28. package/dist/fiscal-server.js +26 -3
  29. package/dist/fiscal-server.js.map +1 -1
  30. package/dist/voucher-document-FWH4DQ5N.js +72 -0
  31. package/dist/voucher-document-FWH4DQ5N.js.map +1 -0
  32. package/dist/voucher-pdf-LQC333AB.js +213 -0
  33. package/dist/voucher-pdf-LQC333AB.js.map +1 -0
  34. package/package.json +1 -1
  35. package/dist/chunk-TXEYBDFG.js +0 -182
  36. package/dist/chunk-TXEYBDFG.js.map +0 -1
  37. package/dist/voucher-document-SFWJCLTN.js +0 -124
  38. package/dist/voucher-document-SFWJCLTN.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { voucherOf } from './chunk-TXEYBDFG.js';
1
+ import { voucherOf } from './chunk-BXKV2KWZ.js';
2
2
  import { isStorefrontError, invoiceFileBytes, safeInvoiceFilename, repairPath } from '@asteby/storefront';
3
3
 
4
4
  async function loadAccountSessions(customer, options = {}) {
@@ -325,16 +325,30 @@ async function invoiceFileResponse({ storefront, orderId, invoiceId, kind, signa
325
325
  return failureResponse(err);
326
326
  }
327
327
  }
328
- async function pendingVoucherResponse({ storefront, id, download = false, shopName, locale, timeZone, signal }) {
328
+ async function pendingVoucherResponse({ storefront, id, download = false, format = "html", paper, pdfHref = "?formato=pdf", shopName, locale, timeZone, signal }) {
329
329
  try {
330
330
  const page = await storefront.customer.pendingPayments({ first: 100 }, signal ? { signal } : void 0);
331
331
  const item = page.nodes.find((p) => p.id === id);
332
332
  const voucher = item ? voucherOf(item) : null;
333
333
  if (!item || !voucher) return textResponse(404, "Ficha no encontrada");
334
- const nonce = btoa(String.fromCharCode(...crypto.getRandomValues(new Uint8Array(16))));
335
- const { renderVoucherDocument } = await import('./voucher-document-SFWJCLTN.js');
336
- const html = renderVoucherDocument(voucher, { ...shopName ? { shopName } : {}, ...locale ? { locale } : {}, ...timeZone ? { timeZone } : {}, printButton: !download, nonce });
337
334
  const safeId = id.replace(/[^A-Za-z0-9-]/g, "").slice(0, 8) || "ficha";
335
+ if (format === "pdf") {
336
+ const { renderVoucherPdf } = await import('./voucher-pdf-LQC333AB.js');
337
+ const bytes = renderVoucherPdf(voucher, { ...shopName ? { shopName } : {}, ...locale ? { locale } : {}, ...timeZone ? { timeZone } : {}, ...paper ? { paper } : {} });
338
+ return new Response(bytes, {
339
+ status: 200,
340
+ headers: {
341
+ "Content-Type": "application/pdf",
342
+ "Content-Length": String(bytes.byteLength),
343
+ "Content-Disposition": 'attachment; filename="ficha-de-pago.pdf"',
344
+ ...LOCKED_HEADERS,
345
+ "Content-Security-Policy": "default-src 'none'; sandbox"
346
+ }
347
+ });
348
+ }
349
+ const nonce = btoa(String.fromCharCode(...crypto.getRandomValues(new Uint8Array(16))));
350
+ const { renderVoucherDocument } = await import('./voucher-document-FWH4DQ5N.js');
351
+ const html = renderVoucherDocument(voucher, { ...shopName ? { shopName } : {}, ...locale ? { locale } : {}, ...timeZone ? { timeZone } : {}, printButton: !download, ...download ? {} : { pdfHref }, nonce });
338
352
  return new Response(html, {
339
353
  status: 200,
340
354
  headers: {
@@ -349,7 +363,10 @@ async function pendingVoucherResponse({ storefront, id, download = false, shopNa
349
363
  return failureResponse(err);
350
364
  }
351
365
  }
366
+ function pendingVoucherPdfResponse(options) {
367
+ return pendingVoucherResponse({ ...options, format: "pdf" });
368
+ }
352
369
 
353
- export { MAX_INVOICE_FILE_BYTES, SAFE_AUTH_CAPABILITIES, createAccountSettingsAction, createAuthAction, invoiceFileResponse, loadAccountSessions, loadAccountSettings, loadAuthCapabilities, pendingVoucherResponse, safeNextPath, toSettingsFailure };
370
+ export { MAX_INVOICE_FILE_BYTES, SAFE_AUTH_CAPABILITIES, createAccountSettingsAction, createAuthAction, invoiceFileResponse, loadAccountSessions, loadAccountSettings, loadAuthCapabilities, pendingVoucherPdfResponse, pendingVoucherResponse, safeNextPath, toSettingsFailure };
354
371
  //# sourceMappingURL=account-server.js.map
355
372
  //# sourceMappingURL=account-server.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/account/settings-server.ts","../src/account/server.ts"],"names":["isStorefrontError","fail"],"mappings":"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","file":"account-server.js","sourcesContent":["/**\n * Server side of the account settings (`@asteby/storefront-react/account/server`): `loadAccountSessions` for the loader\n * and `createAccountSettingsAction` for the action. No React, no router: Web `Request`/`Response` only.\n *\n * The browser never talks to OPS and never sees the buyer's token: the action reads it from the store's own cookie\n * (passed in), builds a client with it (`withCustomerToken`) and calls the contract. Answers carry codes\n * (`SettingsErrorCode`), never a server message, a value of the buyer or a credential; nothing is logged here.\n */\nimport { isStorefrontError, type Customer, type CustomerCapabilities, type CustomerSessionInfo, type StorefrontClient, type StorefrontError } from '@asteby/storefront'\nimport type { AuthCookie } from './server.js'\nimport type { AccountSettingsActionData, SettingsErrorCode, SettingsIntent } from './settings-types.js'\n\nexport type { AccountSettingsActionData, SettingsErrorCode, SettingsIntent } from './settings-types.js'\n\n/** The store's cookie for the buyer session token. React Router's `createCookie(...)` and Remix's fit as they are. */\nexport type SettingsCookie = AuthCookie & {\n parse(header: string | null): unknown | Promise<unknown>\n}\n\n/**\n * The buyer's sessions for the loader. NEVER throws: a store whose server is older than contract 1.9, an outage or an\n * expired session is `null`, and `<SessionsList sessions={null}>` degrades while the rest of the page renders.\n */\nexport async function loadAccountSessions(customer: StorefrontClient, options: { signal?: AbortSignal } = {}): Promise<CustomerSessionInfo[] | null> {\n try {\n return await customer.customer.sessions.list(options.signal ? { signal: options.signal } : undefined)\n } catch {\n return null\n }\n}\n\n/** Everything the settings page reads, each part on its own: a part that cannot be read is `null` and its section degrades. */\nexport type AccountSettingsData = {\n customer: Customer | null\n capabilities: CustomerCapabilities | null\n sessions: CustomerSessionInfo[] | null\n}\n\n/**\n * The loader of the whole settings page. NEVER throws and never fails as a whole: the three reads run together and a\n * failed one (older server, outage, expired session) is `null` for that part only. `customer` is `null` also when the\n * buyer's session is dead: the page should then send them to sign in.\n */\nexport async function loadAccountSettings(customer: StorefrontClient, options: { signal?: AbortSignal } = {}): Promise<AccountSettingsData> {\n const o = options.signal ? { signal: options.signal } : undefined\n const [profile, capabilities, sessions] = await Promise.all([\n customer.customer.get(o).catch(() => null),\n customer.customer.capabilities(o).catch(() => null),\n loadAccountSessions(customer, options),\n ])\n return { customer: profile, capabilities, sessions }\n}\n\nexport type CreateAccountSettingsActionOptions = {\n /** The store's own client (`sk_` token, no buyer). */\n storefront: StorefrontClient\n /** The store's cookie holding the buyer session token. */\n customerCookie: SettingsCookie\n /** Shopper IP for the per-shopper rate limit (see `clientIp` of the client). */\n clientIp?: (request: Request) => string | null | undefined\n}\n\nexport type AccountSettingsActionArgs = { request: Request }\n\nexport const fail = (intent: SettingsIntent | undefined, code: SettingsErrorCode, extra: { field?: string; retryAfter?: number } = {}): AccountSettingsActionData => ({\n ok: false,\n ...(intent ? { intent } : {}),\n error: { code, ...(extra.field ? { field: extra.field } : {}), ...(extra.retryAfter ? { retryAfter: extra.retryAfter } : {}) },\n})\n\n/** Maps what the SDK threw to the code the form shows. `ctx: 'credential'` is a call that checks the buyer's password or code. */\nexport function toSettingsFailure(err: unknown, intent: SettingsIntent | undefined, ctx: 'credential' | 'other' = 'other'): AccountSettingsActionData {\n if (!isStorefrontError(err)) return fail(intent, 'unavailable')\n const e: StorefrontError = err\n if (e.code === 'insufficient_scope') return fail(intent, 'unsupported')\n switch (e.status) {\n case 401:\n return fail(intent, 'session_expired')\n case 403:\n return fail(intent, e.code === 'reauth_required' ? 'reauth_required' : 'unsupported')\n case 404:\n return fail(intent, 'unsupported')\n case 409:\n return fail(intent, e.field === 'orders' ? 'blocked_orders' : e.field === 'pending_payments' ? 'blocked_pending_payments' : 'validation', e.field ? { field: e.field } : {})\n case 429: {\n const wait = typeof e.retryAfter === 'number' && Number.isFinite(e.retryAfter) && e.retryAfter > 0 ? Math.min(3600, Math.ceil(e.retryAfter)) : undefined\n return fail(intent, 'rate_limited', wait ? { retryAfter: wait } : {})\n }\n case 400:\n case 422:\n return ctx === 'credential' ? fail(intent, 'invalid_credential') : fail(intent, 'validation', e.field ? { field: e.field } : {})\n default:\n return fail(intent, 'unavailable')\n }\n}\n\n/**\n * The settings action: one `POST` form with an `intent` field.\n *\n * | intent | fields | result |\n * | ----------------------- | ------------ | ---------------------------------------- |\n * | `session-revoke` | session_id | closes that session (idempotent) |\n * | `session-revoke-others` | - | closes every session but this one |\n * | `locale` | locale | saves the language (`''` = the store's) |\n * | `notifications` | pref, pref_shown | saves the checked / unchecked boxes |\n *\n * It answers `AccountSettingsActionData` to render with the section that sent it. A buyer without a session is\n * `session_expired` (the store redirects to sign-in).\n */\nexport function createAccountSettingsAction(options: CreateAccountSettingsActionOptions) {\n const { storefront: sf, customerCookie } = options\n\n return async function settingsAction({ request }: AccountSettingsActionArgs): Promise<Response | AccountSettingsActionData> {\n // Every intent changes the account (or spends a sign-in code), and the buyer's cookie rides along: a form that\n // another site submits is refused before anything is read. `Sec-Fetch-Site` is set by the browser and cannot be\n // forged by a page; an older browser that omits it falls back to the cookie's SameSite.\n if (request.headers.get('Sec-Fetch-Site')?.toLowerCase() === 'cross-site') return fail(undefined, 'validation')\n const form = await request.formData().catch(() => null)\n if (!form) return fail(undefined, 'validation')\n const text = (name: string) => {\n const v = form.get(name)\n return typeof v === 'string' ? v : ''\n }\n const intent = text('intent') as SettingsIntent\n const raw = await customerCookie.parse(request.headers.get('Cookie'))\n const token = typeof raw === 'string' && raw ? raw : null\n if (!token) return fail(intent, 'session_expired')\n const ip = options.clientIp?.(request)\n const w = ip ? { clientIp: ip } : undefined\n const customer = sf.withCustomerToken(token)\n\n try {\n switch (intent) {\n case 'session-revoke': {\n const id = text('session_id').trim()\n if (!id || id.length > 64) return fail(intent, 'validation', { field: 'session_id' })\n // `others` is its own intent: never let the field spell it, so one button cannot do the other's work.\n if (id.toLowerCase() === 'others') return fail(intent, 'validation', { field: 'session_id' })\n await customer.customer.sessions.revoke(id, w)\n return { ok: true, intent }\n }\n case 'session-revoke-others': {\n await customer.customer.sessions.revokeOthers(w)\n return { ok: true, intent }\n }\n case 'locale': {\n const locale = text('locale').trim()\n if (locale.length > 35) return fail(intent, 'validation', { field: 'locale' })\n await customer.customer.update({ locale: locale || null }, w)\n return { ok: true, intent, saved: true }\n }\n case 'notifications': {\n const shown = form.getAll('pref_shown').filter((v): v is string => typeof v === 'string')\n const checked = new Set(form.getAll('pref').filter((v): v is string => typeof v === 'string'))\n if (shown.length === 0 || shown.length > 30) return fail(intent, 'validation', { field: 'preferences' })\n const notifications: Record<string, Record<string, boolean>> = {}\n for (const pair of shown) {\n const m = /^([a-z][a-z0-9_]{0,31}):([a-z][a-z0-9_]{0,31})$/.exec(pair)\n if (!m) return fail(intent, 'validation', { field: 'preferences' })\n ;(notifications[m[1]!] ??= {})[m[2]!] = checked.has(pair)\n }\n await customer.customer.update({ preferences: { notifications } }, w)\n return { ok: true, intent, saved: true }\n }\n default:\n return fail(undefined, 'validation')\n }\n } catch (err) {\n // A session that is already gone (404) is what the buyer wanted; a stranger's looks the same, by design.\n if (intent === 'session-revoke' && isStorefrontError(err) && err.status === 404) return { ok: true, intent }\n return toSettingsFailure(err, intent)\n }\n }\n}\n\nexport type AccountSettingsAction = ReturnType<typeof createAccountSettingsAction>\n","/**\n * Server side of the account screen (`@asteby/storefront-react/account/server`): `loadAuthCapabilities` for the loader\n * and `createAuthAction` for the action. No React, no router: Web `Request`/`Response` only, so any framework mounts it.\n *\n * The browser never talks to OPS. The action signs the buyer in with the store's `sk_` client and keeps the session\n * token in the store's own cookie, which is passed in (`customerCookie`), so name, flags and signing stay the store's.\n */\nimport { invoiceFileBytes, isStorefrontError, repairPath, safeInvoiceFilename, type CustomerCapabilities, type CustomerSession, type StorefrontClient } from '@asteby/storefront'\nimport { voucherOf } from './voucher.js'\nimport type { AuthActionData, AuthErrorCode, AuthIntent } from './types.js'\n\nexport type { AuthActionData, AuthErrorCode, AuthIntent, AuthStep } from './types.js'\n\n/** What is assumed when the store cannot be asked: password sign-in works, nothing else is offered. */\nexport const SAFE_AUTH_CAPABILITIES: Readonly<CustomerCapabilities> = Object.freeze({\n password: true,\n email_verification: false,\n otp_channels: Object.freeze([]) as unknown as CustomerCapabilities['otp_channels'],\n})\n\nconst FAILURE_TTL_MS = 5_000\nconst LOG_EVERY_MS = 60_000\nlet lastLogAt = -Infinity\n\n/** Server log (never the buyer's data): says what is missing and where it is repaired. At most once a minute. */\nfunction logMisconfigured(scopes: readonly string[]): void {\n const t = Date.now()\n if (t - lastLogAt < LOG_EVERY_MS) return\n lastLogAt = t\n console.error(\n `[@asteby/storefront-react] La credencial de la tienda no tiene permisos${scopes.length ? ` (${scopes.join(', ')})` : ''}; ` +\n `las cuentas de comprador no funcionan hasta repararlo en ${repairPath()}.`,\n )\n}\nconst cache = new WeakMap<object, { at: number; ok: boolean; value: CustomerCapabilities }>()\n\nexport type LoadAuthCapabilitiesOptions = {\n /** How long a good answer is reused per client (default 60 s). `0` disables the cache. */\n ttlMs?: number\n signal?: AbortSignal\n /** Clock, for tests. */\n now?: () => number\n}\n\n/**\n * Asks the store which ways of signing in it offers, with a short cache per client. It NEVER throws: when OPS does not\n * answer (older server, outage, token without scope) it returns `SAFE_AUTH_CAPABILITIES` and retries after a few\n * seconds, so the account screen always renders. Use it as the loader: `loader = () => loadAuthCapabilities(storefront)`.\n */\nexport async function loadAuthCapabilities(sf: StorefrontClient, options: LoadAuthCapabilitiesOptions = {}): Promise<CustomerCapabilities> {\n const now = options.now ?? Date.now\n const ttl = options.ttlMs ?? 60_000\n const hit = cache.get(sf)\n if (hit && now() - hit.at < (hit.ok ? ttl : FAILURE_TTL_MS)) return hit.value\n try {\n const got = await sf.customer.capabilities(options.signal ? { signal: options.signal } : undefined)\n const missing = Array.isArray(got?.missing_scopes) ? got.missing_scopes.filter((x): x is string => typeof x === 'string') : []\n const value: CustomerCapabilities = {\n // `password: false` (including for a missing scope) is respected: the form never offers what the token cannot do.\n password: got?.password !== false,\n email_verification: got?.email_verification === true,\n otp_channels: Array.isArray(got?.otp_channels) ? got.otp_channels : [],\n ...(typeof got?.unavailable_reason === 'string' ? { unavailable_reason: got.unavailable_reason } : {}),\n ...(missing.length ? { missing_scopes: missing } : {}),\n }\n if (value.unavailable_reason === 'missing_scope') logMisconfigured(missing)\n cache.set(sf, { at: now(), ok: true, value })\n return value\n } catch (err) {\n if (isStorefrontError(err) && err.code === 'insufficient_scope') {\n // The token cannot even read capabilities: do not offer password sign-in it could not complete.\n const value: CustomerCapabilities = {\n password: false,\n email_verification: false,\n otp_channels: [],\n unavailable_reason: 'missing_scope',\n missing_scopes: err.requiredScopes,\n }\n logMisconfigured(err.requiredScopes)\n cache.set(sf, { at: now(), ok: false, value })\n return value\n }\n cache.set(sf, { at: now(), ok: false, value: SAFE_AUTH_CAPABILITIES })\n return SAFE_AUTH_CAPABILITIES\n }\n}\n\n/** The part of a cookie the action needs. React Router's `createCookie(...)` and Remix's fit as they are. */\nexport type AuthCookie = {\n serialize(value: string, options?: { expires?: Date; maxAge?: number }): string | Promise<string>\n}\n\n/** Allows only a path inside the site (`/account`, `/orders?x=1`); anything else is `fallback`. Blocks `//host` and `/\\host`. */\nexport function safeNextPath(raw: string | null | undefined, fallback = '/account'): string {\n if (typeof raw !== 'string') return fallback\n const v = raw.trim()\n if (!v.startsWith('/') || v.startsWith('//') || v.startsWith('/\\\\') || /[\\u0000-\\u001f\\\\]/.test(v)) return fallback\n return v\n}\n\nexport type CreateAuthActionOptions = {\n storefront: StorefrontClient\n /** The store's cookie for the buyer session token (`createCookie('sf_customer', ...)`). */\n customerCookie: AuthCookie\n /** Validates the `next` field before redirecting (default `safeNextPath`). Return a same-site path. */\n safeNext?: (raw: string | null) => string\n /** Where to go after signing in when there is no `next` (default `/account`). Only used by the default `safeNext`. */\n defaultNext?: string\n /** Shopper IP for the per-shopper rate limit (see `clientIp` of the client). */\n clientIp?: (request: Request) => string | null | undefined\n /** Capabilities source, for tests or a shared cache (default `loadAuthCapabilities`). */\n capabilities?: (sf: StorefrontClient) => Promise<CustomerCapabilities>\n}\n\nexport type AuthActionArgs = { request: Request }\n\nconst fail = (code: AuthErrorCode, extra: Partial<AuthActionData> = {}, field?: string): AuthActionData => ({\n ok: false,\n ...extra,\n error: { code, ...(field ? { field } : {}) },\n})\n\n/** Maps what the SDK threw to the error the form shows. `ctx` tells what a 401 means on this step. */\nfunction toFailure(err: unknown, ctx: 'credentials' | 'code' | 'other', extra: Partial<AuthActionData>): AuthActionData {\n if (!isStorefrontError(err)) return fail('unavailable', extra)\n if (err.code === 'insufficient_scope') {\n logMisconfigured(err.requiredScopes)\n return fail('store_misconfigured', extra)\n }\n switch (err.status) {\n case 401:\n return fail(ctx === 'credentials' ? 'invalid_credentials' : ctx === 'code' ? 'invalid_code' : 'unavailable', extra, ctx === 'code' ? 'code' : undefined)\n case 409:\n return fail('email_taken', extra, 'email')\n case 429:\n return fail('rate_limited', extra)\n case 400:\n case 422:\n return fail('validation', extra, err.field)\n case 403:\n case 404:\n return fail('unsupported', extra)\n default:\n return fail('unavailable', extra)\n }\n}\n\n/**\n * The account action: one `POST` form with an `intent` field.\n *\n * | intent | fields | result |\n * | ------------- | ---------------------------------------- | -------------------------------------------------------- |\n * | `login` | email, password | signs in -> redirect |\n * | `register` | email, password, first_name?, last_name? | `step: 'verify'` or, without verification, redirect |\n * | `verify` | email, code | account ready -> redirect |\n * | `otp-request` | email | `step: 'otp'` (code sent) |\n * | `otp-login` | email, code | signs in -> redirect |\n * | `forgot` | email | `step: 'reset'` (always, so it never says who has an account) |\n * | `reset` | email, code, password | new password and signed in -> redirect |\n *\n * Success is a `303` to `next` (validated by `safeNext`) with `Set-Cookie` holding the session token; anything else is\n * an `AuthActionData` to render with `<AccountAuth data={...}>`. Passwords and codes are never echoed back.\n */\nexport function createAuthAction(options: CreateAuthActionOptions) {\n const { storefront: sf, customerCookie } = options\n const safeNext = options.safeNext ?? ((raw: string | null) => safeNextPath(raw, options.defaultNext ?? '/account'))\n const loadCaps = options.capabilities ?? ((client: StorefrontClient) => loadAuthCapabilities(client))\n\n async function signedIn(session: CustomerSession, next: string): Promise<Response> {\n const expires = new Date(session.expires_at)\n const cookie = await customerCookie.serialize(session.token, Number.isNaN(expires.getTime()) ? undefined : { expires })\n return new Response(null, { status: 303, headers: { Location: next, 'Set-Cookie': cookie } })\n }\n\n return async function authAction({ request }: AuthActionArgs): Promise<Response | AuthActionData> {\n const form = await request.formData().catch(() => null)\n if (!form) return fail('validation')\n const text = (name: string) => {\n const v = form.get(name)\n return typeof v === 'string' ? v : ''\n }\n const intent = text('intent') as AuthIntent\n const email = text('email').trim()\n const password = text('password')\n const code = text('code').replace(/\\s+/g, '')\n const next = safeNext(text('next') || null)\n const ip = options.clientIp?.(request)\n const w = ip ? { clientIp: ip } : undefined\n const carry: Partial<AuthActionData> = { email }\n if (!email) return fail('validation', carry, 'email')\n\n const caps = await loadCaps(sf)\n const passwordOn = caps.password\n // Off because the store's token lacks a scope (not a merchant choice): say so instead of \"not available\".\n const misconfigured = caps.unavailable_reason === 'missing_scope'\n const off = (): AuthActionData => fail(misconfigured ? 'store_misconfigured' : 'unsupported', carry)\n const otpOn = caps.otp_channels.includes('email')\n\n try {\n switch (intent) {\n case 'login': {\n if (!passwordOn) return off()\n if (!password) return fail('validation', carry, 'password')\n return await signedIn(await sf.customer.loginWithPassword({ email, password }, w), next)\n }\n case 'register': {\n if (!passwordOn) return off()\n if (!password) return fail('validation', carry, 'password')\n const res = await sf.customer.register(\n { email, password, ...(text('first_name').trim() ? { first_name: text('first_name').trim() } : {}), ...(text('last_name').trim() ? { last_name: text('last_name').trim() } : {}) },\n w,\n )\n return res.status === 'created' ? await signedIn(res.session, next) : { ok: true, step: 'verify', email }\n }\n case 'verify': {\n if (!code) return fail('validation', carry, 'code')\n return await signedIn(await sf.customer.verifyRegistration({ email, code }, w), next)\n }\n case 'otp-request': {\n if (!otpOn) return off()\n await sf.customer.requestOtp({ email }, w)\n return { ok: true, step: 'otp', email }\n }\n case 'otp-login': {\n if (!otpOn) return off()\n if (!code) return fail('validation', carry, 'code')\n return await signedIn(await sf.customer.createSession({ email, code }, w), next)\n }\n case 'forgot': {\n if (!passwordOn || !otpOn) return off()\n try {\n await sf.customer.requestOtp({ email }, w)\n } catch (err) {\n // Only throttling and a bad email are told; anything else looks the same as success (no account enumeration).\n if (isStorefrontError(err) && (err.status === 429 || err.status === 400)) throw err\n }\n return { ok: true, step: 'reset', email }\n }\n case 'reset': {\n if (!passwordOn) return off()\n if (!code) return fail('validation', carry, 'code')\n if (!password) return fail('validation', carry, 'password')\n await sf.customer.resetPassword({ email, code, password }, w)\n return await signedIn(await sf.customer.loginWithPassword({ email, password }, w), next)\n }\n default:\n return fail('validation', carry)\n }\n } catch (err) {\n const step = intent === 'verify' ? 'verify' : intent === 'otp-login' ? 'otp' : intent === 'reset' || intent === 'forgot' ? 'reset' : undefined\n const ctx = intent === 'login' ? 'credentials' : step ? 'code' : 'other'\n return toFailure(err, ctx, step && intent !== 'forgot' ? { ...carry, step } : carry)\n }\n }\n}\n\nexport type AuthAction = ReturnType<typeof createAuthAction>\n\n// ---------------------------------------------------------------------------\n// Resource routes of the order screens: the invoice file and the printable voucher\n// ---------------------------------------------------------------------------\n\n/** Headers every answer of a buyer route carries, error or not: never cached, never sniffed, never rendered as a page. */\nconst LOCKED_HEADERS = {\n 'Cache-Control': 'private, no-store',\n 'X-Content-Type-Options': 'nosniff',\n 'Referrer-Policy': 'no-referrer',\n 'X-Robots-Tag': 'noindex',\n} as const\nconst TEXT_HEADERS = { ...LOCKED_HEADERS, 'Content-Type': 'text/plain; charset=utf-8', 'Content-Security-Policy': \"default-src 'none'; sandbox\" } as const\nconst textResponse = (status: number, body: string, extra: Record<string, string> = {}) => new Response(body, { status, headers: { ...TEXT_HEADERS, ...extra } })\n\n/** Largest invoice file served (a CFDI PDF is well under 1 MB): anything bigger is refused before it is decoded. */\nexport const MAX_INVOICE_FILE_BYTES = 10 * 1024 * 1024\n\n/** Statuses a buyer-facing route answers with; anything unexpected is a plain 502 (never the upstream message). */\nfunction failureResponse(err: unknown): Response {\n if (isStorefrontError(err)) {\n if (err.status === 401) return textResponse(401, 'Sesion vencida')\n if (err.status === 404) return textResponse(404, 'No encontrado')\n if (err.status === 429) {\n const wait = typeof err.retryAfter === 'number' && Number.isFinite(err.retryAfter) && err.retryAfter > 0 ? Math.min(3600, Math.ceil(err.retryAfter)) : null\n return textResponse(429, 'Demasiados intentos', wait ? { 'Retry-After': String(wait) } : {})\n }\n }\n return textResponse(502, 'No pudimos obtener el archivo')\n}\n\nconst FILE_TYPES: Record<string, string> = { pdf: 'application/pdf', xml: 'application/xml' }\n\nexport type InvoiceFileResponseOptions = {\n /** Client WITH the buyer's session (`storefront.withCustomerToken(token)`). */\n storefront: StorefrontClient\n orderId: string\n invoiceId: string\n /** From the URL (`pdf` | `xml`); anything else is a 404. */\n kind: string | undefined\n signal?: AbortSignal\n /** Largest file served, in bytes (default `MAX_INVOICE_FILE_BYTES`, 10 MB); a bigger one is a generic 502. */\n maxBytes?: number\n}\n\n/**\n * Serves one file of an invoice or credit note to the signed-in buyer: the route handler of the store\n * (`account.order.$id.invoice.$doc.$kind.ts`) is `return invoiceFileResponse({ storefront, orderId, invoiceId, kind })`.\n * The buyer's token and any PAC URL stay on the server; the browser gets bytes with `Content-Disposition: attachment`,\n * `Cache-Control: private, no-store`, `nosniff` and a sandboxing CSP. The content type is taken from `kind`, never\n * from what the API says, so a file cannot make the browser render HTML under your origin. 401/404/429 pass through;\n * anything else is a generic 502 with no upstream detail.\n */\nexport async function invoiceFileResponse({ storefront, orderId, invoiceId, kind, signal, maxBytes = MAX_INVOICE_FILE_BYTES }: InvoiceFileResponseOptions): Promise<Response> {\n if (kind !== 'pdf' && kind !== 'xml') return textResponse(404, 'No encontrado')\n if (!orderId || !invoiceId) return textResponse(404, 'No encontrado')\n try {\n const file = await storefront.customer.invoiceFile(orderId, invoiceId, kind, signal ? { signal } : undefined)\n if (!file) return textResponse(404, 'No encontrado')\n // Checked on the encoded text (4 chars per 3 bytes, whitespace aside) so a huge answer is never decoded.\n if (file.content_base64.length > Math.ceil(maxBytes / 3) * 4 * 1.1 + 64) return textResponse(502, 'No pudimos obtener el archivo')\n const bytes = invoiceFileBytes(file)\n if (bytes.byteLength > maxBytes) return textResponse(502, 'No pudimos obtener el archivo')\n const name = safeInvoiceFilename(file.filename, kind === 'pdf' ? 'factura.pdf' : 'factura.xml')\n const filename = name.toLowerCase().endsWith(`.${kind}`) ? name : `${name}.${kind}`\n return new Response(bytes as BodyInit, {\n status: 200,\n headers: {\n 'Content-Type': FILE_TYPES[kind]!,\n 'Content-Length': String(bytes.byteLength),\n 'Content-Disposition': `attachment; filename=\"${filename}\"`,\n ...LOCKED_HEADERS,\n 'Content-Security-Policy': \"default-src 'none'; sandbox\",\n },\n })\n } catch (err) {\n return failureResponse(err)\n }\n}\n\nexport type PendingVoucherResponseOptions = {\n /** Client WITH the buyer's session. */\n storefront: StorefrontClient\n /** Checkout id (`PendingPayment.id`). */\n id: string\n /** `?descargar=1`: deliver it as a file instead of showing it. */\n download?: boolean\n shopName?: string\n locale?: string\n timeZone?: string\n signal?: AbortSignal\n}\n\n/**\n * The printable A4 voucher of a pending payment of the signed-in buyer. Served only when `id` is in HIS list (the list\n * is scoped by buyer in OPS): any other id is a 404. The document is self-contained, so its CSP allows nothing\n * external, only its own print script (with a per-response nonce) and inline styles.\n */\nexport async function pendingVoucherResponse({ storefront, id, download = false, shopName, locale, timeZone, signal }: PendingVoucherResponseOptions): Promise<Response> {\n try {\n const page = await storefront.customer.pendingPayments({ first: 100 }, signal ? { signal } : undefined)\n const item = page.nodes.find((p) => p.id === id)\n const voucher = item ? voucherOf(item) : null\n if (!item || !voucher) return textResponse(404, 'Ficha no encontrada')\n const nonce = btoa(String.fromCharCode(...crypto.getRandomValues(new Uint8Array(16))))\n const { renderVoucherDocument } = await import('./voucher-document.js')\n const html = renderVoucherDocument(voucher, { ...(shopName ? { shopName } : {}), ...(locale ? { locale } : {}), ...(timeZone ? { timeZone } : {}), printButton: !download, nonce })\n const safeId = id.replace(/[^A-Za-z0-9-]/g, '').slice(0, 8) || 'ficha'\n return new Response(html, {\n status: 200,\n headers: {\n 'Content-Type': 'text/html; charset=utf-8',\n ...LOCKED_HEADERS,\n // The download carries no script, so its policy allows none.\n 'Content-Security-Policy': `default-src 'none'; style-src 'unsafe-inline'; img-src data:; script-src ${download ? \"'none'\" : `'nonce-${nonce}'`}; base-uri 'none'; form-action 'none'; frame-ancestors 'self'`,\n ...(download ? { 'Content-Disposition': `attachment; filename=\"ficha-de-pago-${safeId}.html\"` } : {}),\n },\n })\n } catch (err) {\n return failureResponse(err)\n }\n}\n\n// Account settings (sessions, preferences, export, deletion): see ./settings-server.ts\nexport { createAccountSettingsAction, loadAccountSessions, loadAccountSettings, toSettingsFailure } from './settings-server.js'\nexport type { AccountSettingsAction, AccountSettingsData, AccountSettingsActionArgs, CreateAccountSettingsActionOptions, SettingsCookie } from './settings-server.js'\nexport type { AccountSettingsActionData, SettingsErrorCode, SettingsIntent } from './settings-types.js'\n"]}
1
+ {"version":3,"sources":["../src/account/settings-server.ts","../src/account/server.ts"],"names":["isStorefrontError","fail"],"mappings":"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","file":"account-server.js","sourcesContent":["/**\n * Server side of the account settings (`@asteby/storefront-react/account/server`): `loadAccountSessions` for the loader\n * and `createAccountSettingsAction` for the action. No React, no router: Web `Request`/`Response` only.\n *\n * The browser never talks to OPS and never sees the buyer's token: the action reads it from the store's own cookie\n * (passed in), builds a client with it (`withCustomerToken`) and calls the contract. Answers carry codes\n * (`SettingsErrorCode`), never a server message, a value of the buyer or a credential; nothing is logged here.\n */\nimport { isStorefrontError, type Customer, type CustomerCapabilities, type CustomerSessionInfo, type StorefrontClient, type StorefrontError } from '@asteby/storefront'\nimport type { AuthCookie } from './server.js'\nimport type { AccountSettingsActionData, SettingsErrorCode, SettingsIntent } from './settings-types.js'\n\nexport type { AccountSettingsActionData, SettingsErrorCode, SettingsIntent } from './settings-types.js'\n\n/** The store's cookie for the buyer session token. React Router's `createCookie(...)` and Remix's fit as they are. */\nexport type SettingsCookie = AuthCookie & {\n parse(header: string | null): unknown | Promise<unknown>\n}\n\n/**\n * The buyer's sessions for the loader. NEVER throws: a store whose server is older than contract 1.9, an outage or an\n * expired session is `null`, and `<SessionsList sessions={null}>` degrades while the rest of the page renders.\n */\nexport async function loadAccountSessions(customer: StorefrontClient, options: { signal?: AbortSignal } = {}): Promise<CustomerSessionInfo[] | null> {\n try {\n return await customer.customer.sessions.list(options.signal ? { signal: options.signal } : undefined)\n } catch {\n return null\n }\n}\n\n/** Everything the settings page reads, each part on its own: a part that cannot be read is `null` and its section degrades. */\nexport type AccountSettingsData = {\n customer: Customer | null\n capabilities: CustomerCapabilities | null\n sessions: CustomerSessionInfo[] | null\n}\n\n/**\n * The loader of the whole settings page. NEVER throws and never fails as a whole: the three reads run together and a\n * failed one (older server, outage, expired session) is `null` for that part only. `customer` is `null` also when the\n * buyer's session is dead: the page should then send them to sign in.\n */\nexport async function loadAccountSettings(customer: StorefrontClient, options: { signal?: AbortSignal } = {}): Promise<AccountSettingsData> {\n const o = options.signal ? { signal: options.signal } : undefined\n const [profile, capabilities, sessions] = await Promise.all([\n customer.customer.get(o).catch(() => null),\n customer.customer.capabilities(o).catch(() => null),\n loadAccountSessions(customer, options),\n ])\n return { customer: profile, capabilities, sessions }\n}\n\nexport type CreateAccountSettingsActionOptions = {\n /** The store's own client (`sk_` token, no buyer). */\n storefront: StorefrontClient\n /** The store's cookie holding the buyer session token. */\n customerCookie: SettingsCookie\n /** Shopper IP for the per-shopper rate limit (see `clientIp` of the client). */\n clientIp?: (request: Request) => string | null | undefined\n}\n\nexport type AccountSettingsActionArgs = { request: Request }\n\nexport const fail = (intent: SettingsIntent | undefined, code: SettingsErrorCode, extra: { field?: string; retryAfter?: number } = {}): AccountSettingsActionData => ({\n ok: false,\n ...(intent ? { intent } : {}),\n error: { code, ...(extra.field ? { field: extra.field } : {}), ...(extra.retryAfter ? { retryAfter: extra.retryAfter } : {}) },\n})\n\n/** Maps what the SDK threw to the code the form shows. `ctx: 'credential'` is a call that checks the buyer's password or code. */\nexport function toSettingsFailure(err: unknown, intent: SettingsIntent | undefined, ctx: 'credential' | 'other' = 'other'): AccountSettingsActionData {\n if (!isStorefrontError(err)) return fail(intent, 'unavailable')\n const e: StorefrontError = err\n if (e.code === 'insufficient_scope') return fail(intent, 'unsupported')\n switch (e.status) {\n case 401:\n return fail(intent, 'session_expired')\n case 403:\n return fail(intent, e.code === 'reauth_required' ? 'reauth_required' : 'unsupported')\n case 404:\n return fail(intent, 'unsupported')\n case 409:\n return fail(intent, e.field === 'orders' ? 'blocked_orders' : e.field === 'pending_payments' ? 'blocked_pending_payments' : 'validation', e.field ? { field: e.field } : {})\n case 429: {\n const wait = typeof e.retryAfter === 'number' && Number.isFinite(e.retryAfter) && e.retryAfter > 0 ? Math.min(3600, Math.ceil(e.retryAfter)) : undefined\n return fail(intent, 'rate_limited', wait ? { retryAfter: wait } : {})\n }\n case 400:\n case 422:\n return ctx === 'credential' ? fail(intent, 'invalid_credential') : fail(intent, 'validation', e.field ? { field: e.field } : {})\n default:\n return fail(intent, 'unavailable')\n }\n}\n\n/**\n * The settings action: one `POST` form with an `intent` field.\n *\n * | intent | fields | result |\n * | ----------------------- | ------------ | ---------------------------------------- |\n * | `session-revoke` | session_id | closes that session (idempotent) |\n * | `session-revoke-others` | - | closes every session but this one |\n * | `locale` | locale | saves the language (`''` = the store's) |\n * | `notifications` | pref, pref_shown | saves the checked / unchecked boxes |\n *\n * It answers `AccountSettingsActionData` to render with the section that sent it. A buyer without a session is\n * `session_expired` (the store redirects to sign-in).\n */\nexport function createAccountSettingsAction(options: CreateAccountSettingsActionOptions) {\n const { storefront: sf, customerCookie } = options\n\n return async function settingsAction({ request }: AccountSettingsActionArgs): Promise<Response | AccountSettingsActionData> {\n // Every intent changes the account (or spends a sign-in code), and the buyer's cookie rides along: a form that\n // another site submits is refused before anything is read. `Sec-Fetch-Site` is set by the browser and cannot be\n // forged by a page; an older browser that omits it falls back to the cookie's SameSite.\n if (request.headers.get('Sec-Fetch-Site')?.toLowerCase() === 'cross-site') return fail(undefined, 'validation')\n const form = await request.formData().catch(() => null)\n if (!form) return fail(undefined, 'validation')\n const text = (name: string) => {\n const v = form.get(name)\n return typeof v === 'string' ? v : ''\n }\n const intent = text('intent') as SettingsIntent\n const raw = await customerCookie.parse(request.headers.get('Cookie'))\n const token = typeof raw === 'string' && raw ? raw : null\n if (!token) return fail(intent, 'session_expired')\n const ip = options.clientIp?.(request)\n const w = ip ? { clientIp: ip } : undefined\n const customer = sf.withCustomerToken(token)\n\n try {\n switch (intent) {\n case 'session-revoke': {\n const id = text('session_id').trim()\n if (!id || id.length > 64) return fail(intent, 'validation', { field: 'session_id' })\n // `others` is its own intent: never let the field spell it, so one button cannot do the other's work.\n if (id.toLowerCase() === 'others') return fail(intent, 'validation', { field: 'session_id' })\n await customer.customer.sessions.revoke(id, w)\n return { ok: true, intent }\n }\n case 'session-revoke-others': {\n await customer.customer.sessions.revokeOthers(w)\n return { ok: true, intent }\n }\n case 'locale': {\n const locale = text('locale').trim()\n if (locale.length > 35) return fail(intent, 'validation', { field: 'locale' })\n await customer.customer.update({ locale: locale || null }, w)\n return { ok: true, intent, saved: true }\n }\n case 'notifications': {\n const shown = form.getAll('pref_shown').filter((v): v is string => typeof v === 'string')\n const checked = new Set(form.getAll('pref').filter((v): v is string => typeof v === 'string'))\n if (shown.length === 0 || shown.length > 30) return fail(intent, 'validation', { field: 'preferences' })\n const notifications: Record<string, Record<string, boolean>> = {}\n for (const pair of shown) {\n const m = /^([a-z][a-z0-9_]{0,31}):([a-z][a-z0-9_]{0,31})$/.exec(pair)\n if (!m) return fail(intent, 'validation', { field: 'preferences' })\n ;(notifications[m[1]!] ??= {})[m[2]!] = checked.has(pair)\n }\n await customer.customer.update({ preferences: { notifications } }, w)\n return { ok: true, intent, saved: true }\n }\n default:\n return fail(undefined, 'validation')\n }\n } catch (err) {\n // A session that is already gone (404) is what the buyer wanted; a stranger's looks the same, by design.\n if (intent === 'session-revoke' && isStorefrontError(err) && err.status === 404) return { ok: true, intent }\n return toSettingsFailure(err, intent)\n }\n }\n}\n\nexport type AccountSettingsAction = ReturnType<typeof createAccountSettingsAction>\n","/**\n * Server side of the account screen (`@asteby/storefront-react/account/server`): `loadAuthCapabilities` for the loader\n * and `createAuthAction` for the action. No React, no router: Web `Request`/`Response` only, so any framework mounts it.\n *\n * The browser never talks to OPS. The action signs the buyer in with the store's `sk_` client and keeps the session\n * token in the store's own cookie, which is passed in (`customerCookie`), so name, flags and signing stay the store's.\n */\nimport { invoiceFileBytes, isStorefrontError, repairPath, safeInvoiceFilename, type CustomerCapabilities, type CustomerSession, type StorefrontClient } from '@asteby/storefront'\nimport { voucherOf } from './voucher.js'\nimport type { AuthActionData, AuthErrorCode, AuthIntent } from './types.js'\n\nexport type { AuthActionData, AuthErrorCode, AuthIntent, AuthStep } from './types.js'\n\n/** What is assumed when the store cannot be asked: password sign-in works, nothing else is offered. */\nexport const SAFE_AUTH_CAPABILITIES: Readonly<CustomerCapabilities> = Object.freeze({\n password: true,\n email_verification: false,\n otp_channels: Object.freeze([]) as unknown as CustomerCapabilities['otp_channels'],\n})\n\nconst FAILURE_TTL_MS = 5_000\nconst LOG_EVERY_MS = 60_000\nlet lastLogAt = -Infinity\n\n/** Server log (never the buyer's data): says what is missing and where it is repaired. At most once a minute. */\nfunction logMisconfigured(scopes: readonly string[]): void {\n const t = Date.now()\n if (t - lastLogAt < LOG_EVERY_MS) return\n lastLogAt = t\n console.error(\n `[@asteby/storefront-react] La credencial de la tienda no tiene permisos${scopes.length ? ` (${scopes.join(', ')})` : ''}; ` +\n `las cuentas de comprador no funcionan hasta repararlo en ${repairPath()}.`,\n )\n}\nconst cache = new WeakMap<object, { at: number; ok: boolean; value: CustomerCapabilities }>()\n\nexport type LoadAuthCapabilitiesOptions = {\n /** How long a good answer is reused per client (default 60 s). `0` disables the cache. */\n ttlMs?: number\n signal?: AbortSignal\n /** Clock, for tests. */\n now?: () => number\n}\n\n/**\n * Asks the store which ways of signing in it offers, with a short cache per client. It NEVER throws: when OPS does not\n * answer (older server, outage, token without scope) it returns `SAFE_AUTH_CAPABILITIES` and retries after a few\n * seconds, so the account screen always renders. Use it as the loader: `loader = () => loadAuthCapabilities(storefront)`.\n */\nexport async function loadAuthCapabilities(sf: StorefrontClient, options: LoadAuthCapabilitiesOptions = {}): Promise<CustomerCapabilities> {\n const now = options.now ?? Date.now\n const ttl = options.ttlMs ?? 60_000\n const hit = cache.get(sf)\n if (hit && now() - hit.at < (hit.ok ? ttl : FAILURE_TTL_MS)) return hit.value\n try {\n const got = await sf.customer.capabilities(options.signal ? { signal: options.signal } : undefined)\n const missing = Array.isArray(got?.missing_scopes) ? got.missing_scopes.filter((x): x is string => typeof x === 'string') : []\n const value: CustomerCapabilities = {\n // `password: false` (including for a missing scope) is respected: the form never offers what the token cannot do.\n password: got?.password !== false,\n email_verification: got?.email_verification === true,\n otp_channels: Array.isArray(got?.otp_channels) ? got.otp_channels : [],\n ...(typeof got?.unavailable_reason === 'string' ? { unavailable_reason: got.unavailable_reason } : {}),\n ...(missing.length ? { missing_scopes: missing } : {}),\n }\n if (value.unavailable_reason === 'missing_scope') logMisconfigured(missing)\n cache.set(sf, { at: now(), ok: true, value })\n return value\n } catch (err) {\n if (isStorefrontError(err) && err.code === 'insufficient_scope') {\n // The token cannot even read capabilities: do not offer password sign-in it could not complete.\n const value: CustomerCapabilities = {\n password: false,\n email_verification: false,\n otp_channels: [],\n unavailable_reason: 'missing_scope',\n missing_scopes: err.requiredScopes,\n }\n logMisconfigured(err.requiredScopes)\n cache.set(sf, { at: now(), ok: false, value })\n return value\n }\n cache.set(sf, { at: now(), ok: false, value: SAFE_AUTH_CAPABILITIES })\n return SAFE_AUTH_CAPABILITIES\n }\n}\n\n/** The part of a cookie the action needs. React Router's `createCookie(...)` and Remix's fit as they are. */\nexport type AuthCookie = {\n serialize(value: string, options?: { expires?: Date; maxAge?: number }): string | Promise<string>\n}\n\n/** Allows only a path inside the site (`/account`, `/orders?x=1`); anything else is `fallback`. Blocks `//host` and `/\\host`. */\nexport function safeNextPath(raw: string | null | undefined, fallback = '/account'): string {\n if (typeof raw !== 'string') return fallback\n const v = raw.trim()\n if (!v.startsWith('/') || v.startsWith('//') || v.startsWith('/\\\\') || /[\\u0000-\\u001f\\\\]/.test(v)) return fallback\n return v\n}\n\nexport type CreateAuthActionOptions = {\n storefront: StorefrontClient\n /** The store's cookie for the buyer session token (`createCookie('sf_customer', ...)`). */\n customerCookie: AuthCookie\n /** Validates the `next` field before redirecting (default `safeNextPath`). Return a same-site path. */\n safeNext?: (raw: string | null) => string\n /** Where to go after signing in when there is no `next` (default `/account`). Only used by the default `safeNext`. */\n defaultNext?: string\n /** Shopper IP for the per-shopper rate limit (see `clientIp` of the client). */\n clientIp?: (request: Request) => string | null | undefined\n /** Capabilities source, for tests or a shared cache (default `loadAuthCapabilities`). */\n capabilities?: (sf: StorefrontClient) => Promise<CustomerCapabilities>\n}\n\nexport type AuthActionArgs = { request: Request }\n\nconst fail = (code: AuthErrorCode, extra: Partial<AuthActionData> = {}, field?: string): AuthActionData => ({\n ok: false,\n ...extra,\n error: { code, ...(field ? { field } : {}) },\n})\n\n/** Maps what the SDK threw to the error the form shows. `ctx` tells what a 401 means on this step. */\nfunction toFailure(err: unknown, ctx: 'credentials' | 'code' | 'other', extra: Partial<AuthActionData>): AuthActionData {\n if (!isStorefrontError(err)) return fail('unavailable', extra)\n if (err.code === 'insufficient_scope') {\n logMisconfigured(err.requiredScopes)\n return fail('store_misconfigured', extra)\n }\n switch (err.status) {\n case 401:\n return fail(ctx === 'credentials' ? 'invalid_credentials' : ctx === 'code' ? 'invalid_code' : 'unavailable', extra, ctx === 'code' ? 'code' : undefined)\n case 409:\n return fail('email_taken', extra, 'email')\n case 429:\n return fail('rate_limited', extra)\n case 400:\n case 422:\n return fail('validation', extra, err.field)\n case 403:\n case 404:\n return fail('unsupported', extra)\n default:\n return fail('unavailable', extra)\n }\n}\n\n/**\n * The account action: one `POST` form with an `intent` field.\n *\n * | intent | fields | result |\n * | ------------- | ---------------------------------------- | -------------------------------------------------------- |\n * | `login` | email, password | signs in -> redirect |\n * | `register` | email, password, first_name?, last_name? | `step: 'verify'` or, without verification, redirect |\n * | `verify` | email, code | account ready -> redirect |\n * | `otp-request` | email | `step: 'otp'` (code sent) |\n * | `otp-login` | email, code | signs in -> redirect |\n * | `forgot` | email | `step: 'reset'` (always, so it never says who has an account) |\n * | `reset` | email, code, password | new password and signed in -> redirect |\n *\n * Success is a `303` to `next` (validated by `safeNext`) with `Set-Cookie` holding the session token; anything else is\n * an `AuthActionData` to render with `<AccountAuth data={...}>`. Passwords and codes are never echoed back.\n */\nexport function createAuthAction(options: CreateAuthActionOptions) {\n const { storefront: sf, customerCookie } = options\n const safeNext = options.safeNext ?? ((raw: string | null) => safeNextPath(raw, options.defaultNext ?? '/account'))\n const loadCaps = options.capabilities ?? ((client: StorefrontClient) => loadAuthCapabilities(client))\n\n async function signedIn(session: CustomerSession, next: string): Promise<Response> {\n const expires = new Date(session.expires_at)\n const cookie = await customerCookie.serialize(session.token, Number.isNaN(expires.getTime()) ? undefined : { expires })\n return new Response(null, { status: 303, headers: { Location: next, 'Set-Cookie': cookie } })\n }\n\n return async function authAction({ request }: AuthActionArgs): Promise<Response | AuthActionData> {\n const form = await request.formData().catch(() => null)\n if (!form) return fail('validation')\n const text = (name: string) => {\n const v = form.get(name)\n return typeof v === 'string' ? v : ''\n }\n const intent = text('intent') as AuthIntent\n const email = text('email').trim()\n const password = text('password')\n const code = text('code').replace(/\\s+/g, '')\n const next = safeNext(text('next') || null)\n const ip = options.clientIp?.(request)\n const w = ip ? { clientIp: ip } : undefined\n const carry: Partial<AuthActionData> = { email }\n if (!email) return fail('validation', carry, 'email')\n\n const caps = await loadCaps(sf)\n const passwordOn = caps.password\n // Off because the store's token lacks a scope (not a merchant choice): say so instead of \"not available\".\n const misconfigured = caps.unavailable_reason === 'missing_scope'\n const off = (): AuthActionData => fail(misconfigured ? 'store_misconfigured' : 'unsupported', carry)\n const otpOn = caps.otp_channels.includes('email')\n\n try {\n switch (intent) {\n case 'login': {\n if (!passwordOn) return off()\n if (!password) return fail('validation', carry, 'password')\n return await signedIn(await sf.customer.loginWithPassword({ email, password }, w), next)\n }\n case 'register': {\n if (!passwordOn) return off()\n if (!password) return fail('validation', carry, 'password')\n const res = await sf.customer.register(\n { email, password, ...(text('first_name').trim() ? { first_name: text('first_name').trim() } : {}), ...(text('last_name').trim() ? { last_name: text('last_name').trim() } : {}) },\n w,\n )\n return res.status === 'created' ? await signedIn(res.session, next) : { ok: true, step: 'verify', email }\n }\n case 'verify': {\n if (!code) return fail('validation', carry, 'code')\n return await signedIn(await sf.customer.verifyRegistration({ email, code }, w), next)\n }\n case 'otp-request': {\n if (!otpOn) return off()\n await sf.customer.requestOtp({ email }, w)\n return { ok: true, step: 'otp', email }\n }\n case 'otp-login': {\n if (!otpOn) return off()\n if (!code) return fail('validation', carry, 'code')\n return await signedIn(await sf.customer.createSession({ email, code }, w), next)\n }\n case 'forgot': {\n if (!passwordOn || !otpOn) return off()\n try {\n await sf.customer.requestOtp({ email }, w)\n } catch (err) {\n // Only throttling and a bad email are told; anything else looks the same as success (no account enumeration).\n if (isStorefrontError(err) && (err.status === 429 || err.status === 400)) throw err\n }\n return { ok: true, step: 'reset', email }\n }\n case 'reset': {\n if (!passwordOn) return off()\n if (!code) return fail('validation', carry, 'code')\n if (!password) return fail('validation', carry, 'password')\n await sf.customer.resetPassword({ email, code, password }, w)\n return await signedIn(await sf.customer.loginWithPassword({ email, password }, w), next)\n }\n default:\n return fail('validation', carry)\n }\n } catch (err) {\n const step = intent === 'verify' ? 'verify' : intent === 'otp-login' ? 'otp' : intent === 'reset' || intent === 'forgot' ? 'reset' : undefined\n const ctx = intent === 'login' ? 'credentials' : step ? 'code' : 'other'\n return toFailure(err, ctx, step && intent !== 'forgot' ? { ...carry, step } : carry)\n }\n }\n}\n\nexport type AuthAction = ReturnType<typeof createAuthAction>\n\n// ---------------------------------------------------------------------------\n// Resource routes of the order screens: the invoice file and the printable voucher\n// ---------------------------------------------------------------------------\n\n/** Headers every answer of a buyer route carries, error or not: never cached, never sniffed, never rendered as a page. */\nconst LOCKED_HEADERS = {\n 'Cache-Control': 'private, no-store',\n 'X-Content-Type-Options': 'nosniff',\n 'Referrer-Policy': 'no-referrer',\n 'X-Robots-Tag': 'noindex',\n} as const\nconst TEXT_HEADERS = { ...LOCKED_HEADERS, 'Content-Type': 'text/plain; charset=utf-8', 'Content-Security-Policy': \"default-src 'none'; sandbox\" } as const\nconst textResponse = (status: number, body: string, extra: Record<string, string> = {}) => new Response(body, { status, headers: { ...TEXT_HEADERS, ...extra } })\n\n/** Largest invoice file served (a CFDI PDF is well under 1 MB): anything bigger is refused before it is decoded. */\nexport const MAX_INVOICE_FILE_BYTES = 10 * 1024 * 1024\n\n/** Statuses a buyer-facing route answers with; anything unexpected is a plain 502 (never the upstream message). */\nfunction failureResponse(err: unknown): Response {\n if (isStorefrontError(err)) {\n if (err.status === 401) return textResponse(401, 'Sesion vencida')\n if (err.status === 404) return textResponse(404, 'No encontrado')\n if (err.status === 429) {\n const wait = typeof err.retryAfter === 'number' && Number.isFinite(err.retryAfter) && err.retryAfter > 0 ? Math.min(3600, Math.ceil(err.retryAfter)) : null\n return textResponse(429, 'Demasiados intentos', wait ? { 'Retry-After': String(wait) } : {})\n }\n }\n return textResponse(502, 'No pudimos obtener el archivo')\n}\n\nconst FILE_TYPES: Record<string, string> = { pdf: 'application/pdf', xml: 'application/xml' }\n\nexport type InvoiceFileResponseOptions = {\n /** Client WITH the buyer's session (`storefront.withCustomerToken(token)`). */\n storefront: StorefrontClient\n orderId: string\n invoiceId: string\n /** From the URL (`pdf` | `xml`); anything else is a 404. */\n kind: string | undefined\n signal?: AbortSignal\n /** Largest file served, in bytes (default `MAX_INVOICE_FILE_BYTES`, 10 MB); a bigger one is a generic 502. */\n maxBytes?: number\n}\n\n/**\n * Serves one file of an invoice or credit note to the signed-in buyer: the route handler of the store\n * (`account.order.$id.invoice.$doc.$kind.ts`) is `return invoiceFileResponse({ storefront, orderId, invoiceId, kind })`.\n * The buyer's token and any PAC URL stay on the server; the browser gets bytes with `Content-Disposition: attachment`,\n * `Cache-Control: private, no-store`, `nosniff` and a sandboxing CSP. The content type is taken from `kind`, never\n * from what the API says, so a file cannot make the browser render HTML under your origin. 401/404/429 pass through;\n * anything else is a generic 502 with no upstream detail.\n */\nexport async function invoiceFileResponse({ storefront, orderId, invoiceId, kind, signal, maxBytes = MAX_INVOICE_FILE_BYTES }: InvoiceFileResponseOptions): Promise<Response> {\n if (kind !== 'pdf' && kind !== 'xml') return textResponse(404, 'No encontrado')\n if (!orderId || !invoiceId) return textResponse(404, 'No encontrado')\n try {\n const file = await storefront.customer.invoiceFile(orderId, invoiceId, kind, signal ? { signal } : undefined)\n if (!file) return textResponse(404, 'No encontrado')\n // Checked on the encoded text (4 chars per 3 bytes, whitespace aside) so a huge answer is never decoded.\n if (file.content_base64.length > Math.ceil(maxBytes / 3) * 4 * 1.1 + 64) return textResponse(502, 'No pudimos obtener el archivo')\n const bytes = invoiceFileBytes(file)\n if (bytes.byteLength > maxBytes) return textResponse(502, 'No pudimos obtener el archivo')\n const name = safeInvoiceFilename(file.filename, kind === 'pdf' ? 'factura.pdf' : 'factura.xml')\n const filename = name.toLowerCase().endsWith(`.${kind}`) ? name : `${name}.${kind}`\n return new Response(bytes as BodyInit, {\n status: 200,\n headers: {\n 'Content-Type': FILE_TYPES[kind]!,\n 'Content-Length': String(bytes.byteLength),\n 'Content-Disposition': `attachment; filename=\"${filename}\"`,\n ...LOCKED_HEADERS,\n 'Content-Security-Policy': \"default-src 'none'; sandbox\",\n },\n })\n } catch (err) {\n return failureResponse(err)\n }\n}\n\nexport type PendingVoucherResponseOptions = {\n /** Client WITH the buyer's session. */\n storefront: StorefrontClient\n /** Checkout id (`PendingPayment.id`). */\n id: string\n /** `?descargar=1`: deliver it as a file instead of showing it. */\n download?: boolean\n /**\n * `html` (default): the printable page. `pdf`: a real `application/pdf` (`ficha-de-pago.pdf`, always an attachment),\n * generated here without a browser. Same ownership check for both.\n */\n format?: 'html' | 'pdf'\n /** Paper of the PDF (default A4). */\n paper?: 'a4' | 'letter'\n /** Where the page's \"Descargar PDF\" link points (default `?formato=pdf` on the same route). */\n pdfHref?: string\n shopName?: string\n locale?: string\n timeZone?: string\n signal?: AbortSignal\n}\n\n/**\n * The printable A4 voucher of a pending payment of the signed-in buyer. Served only when `id` is in HIS list (the list\n * is scoped by buyer in OPS): any other id is a 404. The document is self-contained, so its CSP allows nothing\n * external, only its own print script (with a per-response nonce) and inline styles.\n */\nexport async function pendingVoucherResponse({ storefront, id, download = false, format = 'html', paper, pdfHref = '?formato=pdf', shopName, locale, timeZone, signal }: PendingVoucherResponseOptions): Promise<Response> {\n try {\n const page = await storefront.customer.pendingPayments({ first: 100 }, signal ? { signal } : undefined)\n const item = page.nodes.find((p) => p.id === id)\n const voucher = item ? voucherOf(item) : null\n if (!item || !voucher) return textResponse(404, 'Ficha no encontrada')\n const safeId = id.replace(/[^A-Za-z0-9-]/g, '').slice(0, 8) || 'ficha'\n if (format === 'pdf') {\n const { renderVoucherPdf } = await import('./voucher-pdf.js')\n const bytes = renderVoucherPdf(voucher, { ...(shopName ? { shopName } : {}), ...(locale ? { locale } : {}), ...(timeZone ? { timeZone } : {}), ...(paper ? { paper } : {}) })\n return new Response(bytes as BodyInit, {\n status: 200,\n headers: {\n 'Content-Type': 'application/pdf',\n 'Content-Length': String(bytes.byteLength),\n 'Content-Disposition': 'attachment; filename=\"ficha-de-pago.pdf\"',\n ...LOCKED_HEADERS,\n 'Content-Security-Policy': \"default-src 'none'; sandbox\",\n },\n })\n }\n const nonce = btoa(String.fromCharCode(...crypto.getRandomValues(new Uint8Array(16))))\n const { renderVoucherDocument } = await import('./voucher-document.js')\n const html = renderVoucherDocument(voucher, { ...(shopName ? { shopName } : {}), ...(locale ? { locale } : {}), ...(timeZone ? { timeZone } : {}), printButton: !download, ...(download ? {} : { pdfHref }), nonce })\n return new Response(html, {\n status: 200,\n headers: {\n 'Content-Type': 'text/html; charset=utf-8',\n ...LOCKED_HEADERS,\n // The download carries no script, so its policy allows none.\n 'Content-Security-Policy': `default-src 'none'; style-src 'unsafe-inline'; img-src data:; script-src ${download ? \"'none'\" : `'nonce-${nonce}'`}; base-uri 'none'; form-action 'none'; frame-ancestors 'self'`,\n ...(download ? { 'Content-Disposition': `attachment; filename=\"ficha-de-pago-${safeId}.html\"` } : {}),\n },\n })\n } catch (err) {\n return failureResponse(err)\n }\n}\n\n/** The PDF of a pending payment's voucher: `pendingVoucherResponse` with `format: 'pdf'`. */\nexport function pendingVoucherPdfResponse(options: Omit<PendingVoucherResponseOptions, 'format' | 'download' | 'pdfHref'>): Promise<Response> {\n return pendingVoucherResponse({ ...options, format: 'pdf' })\n}\n\n// Account settings (sessions, preferences, export, deletion): see ./settings-server.ts\nexport { createAccountSettingsAction, loadAccountSessions, loadAccountSettings, toSettingsFailure } from './settings-server.js'\nexport type { AccountSettingsAction, AccountSettingsData, AccountSettingsActionArgs, CreateAccountSettingsActionOptions, SettingsCookie } from './settings-server.js'\nexport type { AccountSettingsActionData, SettingsErrorCode, SettingsIntent } from './settings-types.js'\n"]}