{"version":3,"file":"AuthProvider-On6duCOt.mjs","sources":["../../../libs/frontend-modules/state/src/auth/actions/addError.ts","../../../libs/frontend-modules/state/src/auth/actions/clearErrors.ts","../../../libs/frontend-modules/state/src/auth/actions/notifyAuthenticated.ts","../../../libs/frontend-modules/state/src/auth/actions/notifyUnauthenticated.ts","../../../libs/frontend-modules/state/src/auth/actions/setAccessToken.ts","../../../libs/frontend-modules/state/src/auth/actions/setIgnoreRefreshToken.ts","../../../libs/frontend-modules/state/src/auth/actions/setUserContext.ts","../../../libs/frontend-modules/state/src/auth/actions/unsetRefreshToken.ts","../../../libs/frontend-modules/state/src/auth/actions/unsetUserContext.ts","../../../libs/frontend-modules/state/src/auth/types.ts","../../../libs/frontend-modules/state/src/auth/transport.ts","../../../libs/frontend-modules/state/src/auth/actors/authenticate.ts","../../../libs/frontend-modules/state/src/auth/actors/refreshAccessToken.ts","../../../libs/frontend-modules/state/src/auth/actors/unauthenticate.ts","../../../libs/frontend-modules/state/src/auth/auth.ts","../../../libs/frontend-modules/state/src/auth/AuthProvider.tsx"],"sourcesContent":["import { ErrorActorEvent } from 'xstate';\nimport { AuthMachineContext, AuthMachineEvents } from '../types';\n\nexport function addError({\n  context,\n  event,\n}: {\n  context: AuthMachineContext;\n  event: AuthMachineEvents;\n}) {\n  if (!event.type.includes('xstate.error.actor')) return context;\n\n  const e = event as unknown as ErrorActorEvent;\n  return {\n    errors: [...context.errors, String(e.error).replace('Error: ', '')],\n  };\n}\n\nexport default addError;\n","/** @todo should we assertEvent here? */\nexport function clearErrors() {\n  return {\n    errors: [],\n  };\n}\n\nexport default clearErrors;\n","import { DoneActorEvent } from 'xstate';\nimport {\n  AuthenticatedEmittedEvent,\n  AuthMachineContext,\n  AuthMachineEvents,\n  AuthenticateSuccessEvent,\n  RefreshTokenSuccessEvent,\n} from '../types';\n\nexport function notifyAuthenticated({\n  event,\n}: {\n  context: AuthMachineContext;\n  event: AuthMachineEvents;\n}): AuthenticatedEmittedEvent {\n  if (!event.type.includes('xstate.done.actor'))\n    return { type: 'EMIT_AUTHENTICATED', accessToken: '' };\n\n  const e = event as DoneActorEvent<\n    AuthenticateSuccessEvent | RefreshTokenSuccessEvent\n  >;\n  if (\n    e.output.type !== 'AUTHENTICATE_SUCCESS' &&\n    e.output.type !== 'REFRESH_TOKEN_SUCCESS'\n  )\n    return { type: 'EMIT_AUTHENTICATED', accessToken: '' };\n\n  // A token refresh establishes no new identity, so only a login success\n  // carries the email — see AuthenticatedEmittedEvent.\n  if (e.output.type === 'REFRESH_TOKEN_SUCCESS') {\n    return {\n      type: 'EMIT_AUTHENTICATED',\n      accessToken: e.output.accessToken,\n    };\n  }\n\n  return {\n    type: 'EMIT_AUTHENTICATED',\n    accessToken: e.output.accessToken,\n    email: e.output.user?.email as string | undefined,\n  };\n}\n\nexport default notifyAuthenticated;\n","import { UnauthenticatedEmittedEvent } from '../types';\n\n/** @todo is there ever a case where we don't want to send this event (bad \"unauthentication\") */\nexport function notifyUnauthenticated(): UnauthenticatedEmittedEvent {\n  // no need to do checks since we will send same event no matter what\n  return { type: 'EMIT_UNAUTHENTICATED' };\n}\n\nexport default notifyUnauthenticated;\n","import { DoneActorEvent } from 'xstate';\nimport {\n  RefreshTokenSuccessEvent,\n  AuthMachineContext,\n  AuthMachineEvents,\n} from '../types';\n\nexport function setAccessToken({\n  context,\n  event,\n}: {\n  context: AuthMachineContext;\n  event: AuthMachineEvents;\n}) {\n  if (!event.type.includes('xstate.done.actor')) return context;\n\n  const e = event as DoneActorEvent<RefreshTokenSuccessEvent>;\n  if (e.output.type !== 'REFRESH_TOKEN_SUCCESS') return context;\n\n  return {\n    accessToken: e.output.accessToken,\n    ignoreRefreshToken: false,\n  };\n}\n\nexport default setAccessToken;\n","// there shouldn't be a problem with not checking event here\n// since we can only hit this action from the refresh actor\n// onDone or onError\nexport function setIgnoreRefreshToken() {\n  return {\n    ignoreRefreshToken: true,\n  };\n}\n\nexport default setIgnoreRefreshToken;\n","import { DoneActorEvent } from 'xstate';\nimport {\n  AuthenticateSuccessEvent,\n  AuthMachineContext,\n  AuthMachineEvents,\n} from '../types';\n\nexport function setUserContext({\n  context,\n  event,\n}: {\n  context: AuthMachineContext;\n  event: AuthMachineEvents;\n}) {\n  if (!event.type.includes('xstate.done.actor')) return context;\n\n  const e = event as DoneActorEvent<AuthenticateSuccessEvent>;\n  if (e.output.type !== 'AUTHENTICATE_SUCCESS') return context;\n\n  return {\n    accessToken: e.output.accessToken,\n    ignoreRefreshToken: false,\n    user: e.output.user ?? null,\n  };\n}\n\nexport default setUserContext;\n","// there shouldn't be a problem with not checking event here\n// since we can only hit this action from the refresh actor\n// onDone or onError\nexport function unsetRefreshToken() {\n  return {\n    refreshToken: '',\n  };\n}\n\nexport default unsetRefreshToken;\n","/** @todo should we assertEvent here? */\nexport function unsetUserContext() {\n  return {\n    user: null,\n    accessToken: '',\n    refreshToken: '',\n    ignoreRefreshToken: false,\n  };\n}\n\nexport default unsetUserContext;\n","import { DoneActorEvent } from 'xstate';\nimport { AuthTransport } from './transport';\n\nexport interface AuthMachineContext {\n  /**\n   * Header injection for the auth HTTP calls, supplied by the host when the\n   * actor is created. Injected rather than imported — see `./transport`.\n   * Absent → the hardcoded pre-CTAP-1159 defaults apply.\n   */\n  transport?: AuthTransport;\n  // user: {\n  //   email: string;\n  //   username: string;\n  //   firstName: string;\n  //   lastName: string;\n  //   birthdate?: Date;\n  //   gender?: string /** @todo use enum? */;\n  //   createdAt: Date;\n  //   updatedAt: Date;\n  //   role?: string /** @todo use enum? */;\n  //   locked: boolean;\n  //   affiliateId: string;\n  //   stripeId: string;\n  // } | null;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  user: Record<string, any> | null;\n  accessToken: string;\n  refreshToken: string;\n  ignoreRefreshToken: boolean;\n  /**\n   * Why the session ended, so `unauthenticating` (entered by BOTH a deliberate\n   * LOGOUT and a client-side refresh failure) can route the two differently:\n   * `deliberate` → `loggedOut.afterLogout` (home), `expired` →\n   * `loggedOut.afterRefreshFailure` (return-path redirect). See CTAP-1129.\n   */\n  logoutReason: 'deliberate' | 'expired' | null;\n  endpoints: {\n    login: string;\n    logout: string;\n    refresh: string;\n    ssrRefresh: string;\n  };\n  errors: Array<string>;\n}\n\nexport interface RefreshTokenEvent {\n  type: 'REFRESH_TOKEN';\n  accessToken: AuthMachineContext['accessToken'];\n}\n\nexport interface LoginEvent {\n  type: 'LOGIN';\n  username: string;\n  password: string;\n}\n\nexport interface LogoutEvent {\n  type: 'LOGOUT';\n}\n\n/**\n * The SERVER rejected our access token (a 401 from any authenticated request).\n * Distinct from LOGOUT: an expired session is not a chosen sign-out, so it must\n * route to `afterRefreshFailure` — which keeps the return path to wherever the\n * visitor was — rather than `afterLogout`, which deliberately goes home with no\n * return path (CTAP-1120/1129/1425).\n */\nexport interface SessionExpiredEvent {\n  type: 'SESSION_EXPIRED';\n}\n\n/**\n * A credential-change mutation (email/password) minted a fresh session server-side and returned a\n * new access token; the rotated refresh cookie is already set on the response. Swap the in-memory\n * access token in place so the user stays signed in — no login round-trip.\n */\nexport interface SessionReissuedEvent {\n  type: 'SESSION_REISSUED';\n  accessToken: AuthMachineContext['accessToken'];\n}\n\nexport interface ClearErrorsEvent {\n  type: 'CLEAR_ERRORS';\n}\n\nexport interface RestoreEvent {\n  type: 'RESTORE';\n}\n\n// export interface AfterLoggedInEvent {\n//   type: 'AFTER_LOGGED_IN';\n// }\n\n// export interface AfterLoggedOutEvent {\n//   type: 'AFTER_LOGGED_OUT';\n// }\n\nexport interface AuthenticateSuccessEvent {\n  type: 'AUTHENTICATE_SUCCESS';\n  user: Partial<AuthMachineContext['user']>;\n  accessToken: AuthMachineContext['accessToken'];\n}\n\nexport interface RefreshTokenSuccessEvent {\n  type: 'REFRESH_TOKEN_SUCCESS';\n  accessToken: AuthMachineContext['accessToken'];\n}\n\nexport interface UnauthenticateSuccessEvent {\n  type: 'UNAUTHENTICATE_SUCCESS';\n}\n\nexport interface AuthenticatedEmittedEvent {\n  type: 'EMIT_AUTHENTICATED';\n  accessToken: AuthMachineContext['accessToken'];\n  /**\n   * The signed-in identity, present when the emit follows an AUTHENTICATE\n   * (login) success — identity consumers (GA4 signed_in, Klaviyo identify)\n   * need it at exactly this moment. Absent on token refreshes: a refresh\n   * establishes no new identity.\n   */\n  email?: string;\n}\n\nexport interface UnauthenticatedEmittedEvent {\n  type: 'EMIT_UNAUTHENTICATED';\n}\n\n// type AuthEvents = RefreshTokenEvent | AnotherEvent;\nexport type AuthMachineEvents =\n  | RefreshTokenEvent\n  | RestoreEvent\n  | LoginEvent\n  | LogoutEvent\n  | SessionExpiredEvent\n  | SessionReissuedEvent\n  | ClearErrorsEvent\n  // | AfterLoggedInEvent\n  // | AfterLoggedOutEvent\n  | DoneActorEvent<AuthenticateSuccessEvent>\n  | DoneActorEvent<RefreshTokenSuccessEvent>;\n\nexport type AuthMachineEmittedEvents =\n  AuthenticatedEmittedEvent | UnauthenticatedEmittedEvent;\n\nexport enum AuthMachineStatusCode {\n  INCORRECT_LOGIN_CREDENTIALS = 'INCORRECT_LOGIN_CREDENTIALS',\n  /**\n   * The account is TEMPORARILY locked from signing in after repeated failed\n   * password attempts (e.g. Magento's lockout window, surfaced to the user\n   * as \"Sign-in with this account is unavailable\"). It clears on its own —\n   * hosts branch on this to run a recovery flow (an OTP re-verify step, a\n   * \"try again later\" notice) instead of the incorrect-credentials copy.\n   *\n   * Mapped from the login response's structured `code` field\n   * ({@link AuthenticateResponse.code}) — never from the display message,\n   * which belongs to the backend (Magento's copy can change). A backend that\n   * doesn't emit the code keeps collapsing to INCORRECT_LOGIN_CREDENTIALS.\n   */\n  ACCOUNT_LOCKED = 'ACCOUNT_LOCKED',\n  /**\n   * Sign-in could not be attempted: the server failed (5xx) or could not be reached at all\n   * (offline, DNS, CORS, an aborted request). **No credential decision was made** — the password\n   * may well be correct.\n   *\n   * Separate from INCORRECT_LOGIN_CREDENTIALS because collapsing the two told users their password\n   * was wrong during a server outage. NOCOW-1067 was triaged as a credentials problem for most of a\n   * day on the strength of that copy, and the account holder was asked to reset a working password\n   * (CTAP-1817).\n   *\n   * A host that does not know this code falls through to its own default branch, which is the right\n   * outcome and needs no coordinated release.\n   */\n  AUTHENTICATION_UNAVAILABLE = 'AUTHENTICATION_UNAVAILABLE',\n}\n","/**\n * Header injection for the auth machine's HTTP calls.\n *\n * The auth actors used to hardcode `clicktap-scope: view` /\n * `clicktap-scope-id: default` — fine for a single-storefront app, fatal for\n * anything else: a wholesale/B2B storefront needs the ACTUAL view id, an\n * `Authorization` header, and a `clicktap-company` header on `/auth/login`,\n * `/auth/refresh` and `/auth/logout`, and those values are only known to the\n * host app (and change over the life of the actor). The quote machines got a\n * `QuoteTransport` input precisely to end this kind of hardcoded coupling —\n * this is the same pattern for auth (CTAP-1159).\n *\n * The provider is a FUNCTION, called immediately before each request, so the\n * headers it returns are current at call time — an `Authorization` built from\n * the token at actor creation would go stale after the first refresh, and\n * `clicktap-company` changes when the visitor picks a company. Its return\n * value is merged OVER the defaults, so a host only overrides what it needs:\n *\n *   createActor(authMachine, {\n *     input: {\n *       transport: {\n *         headers: () => ({\n *           'clicktap-scope-id': viewId,\n *           ...(token ? { Authorization: `Bearer ${token}` } : {}),\n *           ...(company ? { 'clicktap-company': company } : {}),\n *         }),\n *       },\n *       initialContext: { … },\n *     },\n *   });\n *\n * Like `QuoteTransport`, the transport lives in machine context and therefore\n * does not survive snapshot serialization — a consumer restoring a persisted\n * snapshot must recreate the actor with the transport supplied again.\n */\n\n/** Which auth request the headers are being resolved for. */\nexport type AuthCall = 'login' | 'refresh' | 'ssrRefresh' | 'logout';\n\n/**\n * Returns the headers to merge over {@link DEFAULT_AUTH_HEADERS} for one call.\n * Invoked per request — return fresh values, don't capture stale ones.\n */\nexport type AuthHeadersProvider = (call: AuthCall) => Record<string, string>;\n\nexport type AuthTransport = {\n  headers?: AuthHeadersProvider;\n};\n\n/**\n * The pre-CTAP-1159 hardcoded values, kept as the default so hosts that never\n * pass a transport behave exactly as before.\n */\nexport const DEFAULT_AUTH_HEADERS: Record<string, string> = {\n  'clicktap-scope': 'view',\n  'clicktap-scope-id': 'default',\n};\n\nexport function resolveAuthHeaders(\n  transport: AuthTransport | undefined,\n  call: AuthCall,\n): Record<string, string> {\n  return {\n    ...DEFAULT_AUTH_HEADERS,\n    ...(transport?.headers?.(call) ?? {}),\n  };\n}\n","import { fromPromise } from 'xstate';\nimport {\n  AuthenticateSuccessEvent,\n  AuthMachineContext,\n  AuthMachineStatusCode,\n} from '../types';\nimport { AuthTransport, resolveAuthHeaders } from '../transport';\nimport { request } from '../../helpers/request';\nimport { isDevelopment } from '../../helpers/env';\n\nexport type AuthenticateInput = {\n  endpoint: {\n    client: AuthMachineContext['endpoints']['login'];\n  };\n  password: string;\n  /** Host-supplied header injection — see `../transport`. */\n  transport?: AuthTransport;\n  username: string;\n};\n\nexport type AuthenticateResponse = {\n  success: boolean;\n  message?: string;\n  /**\n   * Structured failure code (an {@link AuthMachineStatusCode} value, e.g.\n   * `ACCOUNT_LOCKED` for a temporary bad-password lockout). This — never the\n   * display `message` — is what the actor maps to a status code: messages are\n   * backend/Magento display copy and not a contract (CTAP-1197).\n   */\n  code?: string;\n  access_token?: string;\n  /**\n   * HTTP status, present only on a failed response (see `helpers/request`). This — never the\n   * message — is how the actor tells a server failure from a rejected password (CTAP-1817).\n   */\n  status?: number;\n};\n\n// export type AuthenticateTokenOutput = {\n//   type: string;\n//   accessToken: string;\n// };\n\n/** @todo pass locale for auth server? */\nexport const authenticate = fromPromise<\n  AuthenticateSuccessEvent,\n  AuthenticateInput\n>(async ({ input }) => {\n  if (!input.endpoint.client || input.endpoint.client === '') {\n    throw new Error('No client endpoint provided.');\n  }\n\n  // A known AuthMachineStatusCode, or null. The structured `code` is the contract; the display\n  // message is backend copy and never dispatched on (CTAP-1197).\n  const knownCode = (code?: string): AuthMachineStatusCode | null =>\n    code && (Object.values(AuthMachineStatusCode) as string[]).includes(code)\n      ? (code as AuthMachineStatusCode)\n      : null;\n\n  // The original is CHAINED, never discarded: a host that logs the failure needs the real error,\n  // and before CTAP-1817 it was replaced outright.\n  const fail = (code: AuthMachineStatusCode, cause?: unknown): Error => {\n    const error = new Error(code);\n    if (cause !== undefined) {\n      // Assigned rather than passed to the constructor: the `options` argument needs an ES2022\n      // lib, and this package typechecks below that.\n      (error as Error & { cause?: unknown }).cause = cause;\n    }\n\n    return error;\n  };\n\n  let data: AuthenticateResponse;\n  try {\n    data = await request<AuthenticateResponse>(input.endpoint.client, {\n      method: 'POST',\n      mode: 'cors',\n      credentials: 'include',\n      headers: {\n        'Content-Type': 'application/json',\n        ...resolveAuthHeaders(input.transport, 'login'),\n      },\n      body: JSON.stringify({\n        username: input.username,\n        password: input.password,\n      }).toString(),\n    });\n  } catch (err) {\n    // `fetch` itself rejected — offline, DNS, CORS, abort. There is no response, so the server\n    // never saw the credentials and cannot have rejected them.\n    if (isDevelopment) {\n      console.error('[authenticate] transport failure', err);\n    }\n\n    throw fail(AuthMachineStatusCode.AUTHENTICATION_UNAVAILABLE, err);\n  }\n\n  if (!data.success) {\n    if (isDevelopment) {\n      console.error('[authenticate] sign-in failed', data);\n    }\n\n    // A code the backend emitted deliberately wins, whatever the status.\n    const code = knownCode(data.code);\n    if (code) {\n      throw fail(code);\n    }\n\n    // 5xx: the server broke. It made no credential decision, so saying the password is wrong is\n    // not a hedge, it is a false statement — and it is what sent NOCOW-1067 down the wrong path.\n    if (typeof data.status === 'number' && data.status >= 500) {\n      throw fail(\n        AuthMachineStatusCode.AUTHENTICATION_UNAVAILABLE,\n        new Error(data.message ?? `Login endpoint returned ${data.status}`),\n      );\n    }\n\n    // Everything else is the server rejecting the credentials: a 401, or a 200 whose body says\n    // `success: false` without a code. This is the collapse ACCOUNT_LOCKED's docblock describes,\n    // and it is correct HERE — a credential decision was genuinely made.\n    throw fail(\n      AuthMachineStatusCode.INCORRECT_LOGIN_CREDENTIALS,\n      new Error(data.message ?? 'Sign in failed.'),\n    );\n  }\n\n  return {\n    type: 'AUTHENTICATE_SUCCESS',\n    // The signed-in identity — the auth endpoint returns no profile, so the\n    // submitted username (an email) is what identity consumers get.\n    user: { email: input.username },\n    accessToken: data.access_token ?? '',\n  };\n});\n\nexport default authenticate;\n","import { fromPromise } from 'xstate';\nimport { isDevelopment } from '../../helpers/env';\nimport { RefreshTokenSuccessEvent, AuthMachineContext } from '../types';\nimport { AuthTransport, resolveAuthHeaders } from '../transport';\nimport { request } from '../../helpers/request';\n\nexport type RefreshTokenInput = {\n  // accessToken: AuthMachineContext['accessToken'];\n  refreshToken: AuthMachineContext['refreshToken'];\n  endpoint: {\n    client: AuthMachineContext['endpoints']['refresh'];\n    server: AuthMachineContext['endpoints']['ssrRefresh'];\n  };\n  /** Host-supplied header injection — see `../transport`. */\n  transport?: AuthTransport;\n};\n\nexport type RefreshTokenResponse = {\n  access_token?: string;\n};\n\nexport type RefreshTokenOutput = {\n  type: string;\n  accessToken: string;\n};\n\nconst IS_SERVER = typeof window === 'undefined';\n\n/** @todo pass locale for auth server? */\nexport const refreshAccessToken = fromPromise<\n  RefreshTokenSuccessEvent,\n  RefreshTokenInput\n>(async ({ input }) => {\n  if (!input.endpoint.client || input.endpoint.client === '') {\n    if (isDevelopment) {\n      console.log('refreshAccessToken: No client endpoint provided.');\n    }\n    throw new Error('No client endpoint provided.');\n  }\n  // The server endpoint is only called on the server; the browser has none to give (CTAP-2026).\n  if (IS_SERVER && !input.endpoint.server) {\n    if (isDevelopment) {\n      console.log('refreshAccessToken: No server endpoint provided.');\n    }\n    throw new Error('No server endpoint provided.');\n  }\n  // if (!input.accessToken) throw new Error('No access token provided.');\n\n  let data: RefreshTokenResponse;\n\n  if (IS_SERVER) {\n    if (input.refreshToken === '') throw new Error('Unauthorized.');\n\n    try {\n      data = await request<RefreshTokenResponse>(input.endpoint.server, {\n        method: 'POST',\n        mode: 'cors',\n        credentials: 'include',\n        headers: {\n          Cookie: `refresh_token=${input.refreshToken}`,\n          'Content-Type': 'application/json',\n          ...resolveAuthHeaders(input.transport, 'ssrRefresh'),\n        },\n      });\n\n      if (typeof data.access_token === 'undefined') {\n        throw new Error('Unauthorized.');\n      }\n\n      return {\n        type: 'REFRESH_TOKEN_SUCCESS',\n        accessToken: data.access_token,\n      } as RefreshTokenSuccessEvent;\n    } catch (err) {\n      if (isDevelopment) {\n        console.log(err);\n      }\n      throw new Error('Could not complete refresh request (server)');\n    }\n  } else {\n    // client\n    data = await request<RefreshTokenResponse>(input.endpoint.client, {\n      method: 'POST',\n      mode: 'cors',\n      credentials: 'include',\n      headers: {\n        'Content-Type': 'application/json',\n        ...resolveAuthHeaders(input.transport, 'refresh'),\n      },\n      /** @todo is this necessary anymore? */\n      body: JSON.stringify({\n        grant_type: 'refresh_token',\n        // client_id: 'default',\n        // client_secret: 'Password123!',\n        // scope: 'default',\n      }).toString(),\n    });\n\n    if (typeof data.access_token === 'undefined') {\n      throw new Error('Unauthorized.');\n    }\n\n    return {\n      type: 'REFRESH_TOKEN_SUCCESS',\n      accessToken: data.access_token,\n    };\n  }\n});\n\nexport default refreshAccessToken;\n","import { fromPromise } from 'xstate';\nimport { UnauthenticateSuccessEvent, AuthMachineContext } from '../types';\nimport { AuthTransport, resolveAuthHeaders } from '../transport';\n\nexport type UnauthenticateInput = {\n  endpoint: {\n    client: AuthMachineContext['endpoints']['logout'];\n  };\n  /** Host-supplied header injection — see `../transport`. */\n  transport?: AuthTransport;\n};\n\nexport type UnauthenticateResponse = {\n  success: boolean;\n  message?: string;\n  accessToken?: string;\n};\n\n// export type UnauthenticateOutput = {\n//   type: string;\n//   accessToken: string;\n// };\n\n/** @todo pass locale for auth server? */\nexport const unauthenticate = fromPromise<\n  UnauthenticateSuccessEvent,\n  UnauthenticateInput\n>(async ({ input }) => {\n  if (!input.endpoint.client || input.endpoint.client === '') {\n    console.log('unauthenticate: No client endpoint provided.');\n    throw new Error('No client endpoint provided.');\n  }\n\n  try {\n    await fetch(input.endpoint.client, {\n      method: 'POST',\n      mode: 'cors',\n      credentials: 'include',\n      headers: resolveAuthHeaders(input.transport, 'logout'),\n      // headers: {\n      //   'Access-Control-Allow-Origin': 'https://pwa-demo.rmgmedia.com',\n      //   'Access-Control-Allow-Credentials': 'true',\n      // },\n    });\n\n    return { type: 'UNAUTHENTICATE_SUCCESS' };\n  } catch (err) {\n    console.log(err);\n    throw new Error('Could not complete unauthenticate request (server)');\n  }\n  /** @todo do we need to handle different status codes here...like what if the service is down? */\n  // const data = await response.json();\n});\n\nexport default unauthenticate;\n","import { assertEvent, assign, emit, setup } from 'xstate';\nimport { AuthTransport } from './transport';\nimport {\n  AuthMachineContext,\n  AuthMachineEmittedEvents,\n  AuthMachineEvents,\n} from './types';\nimport {\n  addError as addErrorAction,\n  clearErrors as clearErrorsAction,\n  notifyAuthenticated as notifyAuthenticatedAction,\n  notifyUnauthenticated as notifyUnauthenticatedAction,\n  setAccessToken as setAccessTokenAction,\n  setIgnoreRefreshToken as setIgnoreRefreshTokenAction,\n  setUserContext as setUserContextAction,\n  unsetRefreshToken as unsetRefreshTokenAction,\n  unsetUserContext as unsetUserContextAction,\n} from './actions';\nimport {\n  authenticate as authenticateActor,\n  refreshAccessToken as refreshAccessTokenActor,\n  unauthenticate as unauthenticateActor,\n} from './actors';\n\nexport const authMachine = setup({\n  types: {\n    context: {} as AuthMachineContext,\n    emitted: {} as AuthMachineEmittedEvents,\n    events: {} as AuthMachineEvents,\n    input: {} as {\n      /**\n       * Header injection for the auth HTTP calls — see `./transport`.\n       * Optional: without it the actors send the historical hardcoded\n       * `clicktap-scope: view` / `clicktap-scope-id: default`.\n       */\n      transport?: AuthTransport;\n      initialContext: Partial<AuthMachineContext>;\n      initialState?: string;\n    },\n  },\n  actions: {\n    addError: assign(addErrorAction),\n    clearErrors: assign(clearErrorsAction),\n    notifyAuthenticated: emit(notifyAuthenticatedAction),\n    notifyUnauthenticated: emit(notifyUnauthenticatedAction),\n    setAccessToken: assign(setAccessTokenAction),\n    // A credential-change mutation returned a fresh access token (refresh cookie already rotated\n    // server-side); swap it into context and re-announce authentication with the new token.\n    setReissuedAccessToken: assign(({ event }) => {\n      assertEvent(event, 'SESSION_REISSUED');\n      return { accessToken: event.accessToken, ignoreRefreshToken: false };\n    }),\n    notifyReissued: emit(({ event }) => {\n      assertEvent(event, 'SESSION_REISSUED');\n      return {\n        type: 'EMIT_AUTHENTICATED' as const,\n        accessToken: event.accessToken,\n      };\n    }),\n    setIgnoreRefreshToken: assign(setIgnoreRefreshTokenAction),\n    // Record why the session is ending so `unauthenticating` can route a\n    // deliberate sign-out (→ home) apart from an expired session (→ return-path\n    // redirect), even though both pass through the same state (CTAP-1129).\n    markDeliberateLogout: assign(() => ({\n      logoutReason: 'deliberate' as const,\n    })),\n    markExpiredSession: assign(() => ({ logoutReason: 'expired' as const })),\n    setUserContext: assign(setUserContextAction),\n    unsetRefreshToken: assign(unsetRefreshTokenAction),\n    unsetUserContext: assign(unsetUserContextAction),\n  },\n  actors: {\n    authenticate: authenticateActor,\n    refreshAccessToken: refreshAccessTokenActor,\n    unauthenticate: unauthenticateActor,\n  },\n  delays: {\n    refresh: 840000,\n  },\n}).createMachine({\n  id: 'auth',\n  context: ({ input }) => ({\n    transport: input?.transport,\n    user: null,\n    accessToken: '',\n    refreshToken: '', // will only be on the request from the server side for initial check, does not get passed to the client\n    /**\n     * If unauthenticating fails, we need a way to ignore the refresh token on subsequent access token refresh.\n     * This would be set to true done/error of unauthenticate service, and false on done of authenticate service\n     */\n    ignoreRefreshToken: false,\n    logoutReason: null,\n    endpoints: {\n      login: '',\n      logout: '',\n      refresh: '',\n      ssrRefresh: '',\n    },\n    errors: [],\n    ...input?.initialContext,\n  }),\n  initial: 'initializing',\n  states: {\n    initializing: {\n      always: [\n        {\n          target: 'loggedIn',\n          guard: ({ context }) => !!context.accessToken,\n        },\n        {\n          target: 'loggedOut.initial',\n        },\n      ],\n    },\n    authenticating: {\n      invoke: {\n        src: 'authenticate',\n        input: ({ context, event }) => {\n          assertEvent(event, 'LOGIN');\n\n          return {\n            endpoint: {\n              client: context.endpoints.login,\n            },\n            transport: context.transport,\n            username: event.username,\n            password: event.password,\n          };\n        },\n        onDone: [\n          {\n            actions: ['setUserContext', 'notifyAuthenticated'],\n            target: 'loggedIn',\n          },\n        ],\n        onError: [\n          {\n            actions: 'addError',\n            target: 'loggedOut.afterFailedAuth',\n          },\n        ],\n      },\n    },\n    unauthenticating: {\n      invoke: {\n        src: 'unauthenticate',\n        input: ({ context }) => {\n          return {\n            endpoint: {\n              client: context.endpoints.logout,\n            },\n            transport: context.transport,\n          };\n        },\n        // `unauthenticating` is reached by a deliberate LOGOUT *and* by a\n        // client-side refresh failure (see `refreshing.onError`). Route them\n        // apart on `logoutReason`: an expired session goes to\n        // `afterRefreshFailure` (→ getRedirectPath keeps the return path), so\n        // only a deliberate sign-out lands in `afterLogout` (→ home). CTAP-1129.\n        onDone: [\n          {\n            guard: ({ context }) => context.logoutReason === 'expired',\n            actions: ['unsetUserContext', 'notifyUnauthenticated'],\n            target: 'loggedOut.afterRefreshFailure',\n          },\n          {\n            actions: ['unsetUserContext', 'notifyUnauthenticated'],\n            target: 'loggedOut.afterLogout',\n          },\n        ],\n        onError: [\n          {\n            guard: ({ context }) => context.logoutReason === 'expired',\n            actions: [\n              'unsetUserContext',\n              'setIgnoreRefreshToken',\n              'notifyUnauthenticated',\n            ],\n            target: 'loggedOut.afterRefreshFailure',\n          },\n          {\n            actions: [\n              'unsetUserContext',\n              'setIgnoreRefreshToken',\n              'notifyUnauthenticated',\n            ],\n            target: 'loggedOut.afterLogout',\n          },\n        ],\n      },\n    },\n    refreshing: {\n      invoke: {\n        src: 'refreshAccessToken',\n        input: ({ context }) => {\n          return {\n            accessToken: context.accessToken,\n            endpoint: {\n              client: context.endpoints.refresh,\n              server: context.endpoints.ssrRefresh,\n            },\n            refreshToken: context.refreshToken,\n            transport: context.transport,\n          };\n        },\n        onDone: [\n          {\n            actions: [\n              'unsetRefreshToken',\n              'setAccessToken',\n              'notifyAuthenticated',\n            ],\n            guard: () => typeof window !== 'undefined',\n            target: 'loggedIn',\n          },\n          /**\n           * We must transition to transient loggedInReady state from server-side refresh\n           * so the frontend can send RESTORE event. Otherwise actions and timers from\n           * loggedIn state won't fire properly from client (known issue in xstate)\n           */\n          {\n            actions: ['unsetRefreshToken', 'setAccessToken'],\n            target: 'loggedInReady',\n          },\n        ],\n        /**\n         * @todo\n         * confirm this logic, does it make sense to unset refresh token\n         * if the request fails for some reason on server side?\n         */\n        onError: [\n          // logout can only happen on the client side, so we\n          // guard the action to prevent it from happening on the server\n          // and fall back to loggedOut state server-side\n          {\n            // Client-side refresh failure = an EXPIRED session, not a\n            // deliberate sign-out; mark it so `unauthenticating` routes it to\n            // afterRefreshFailure (return-path), not home (CTAP-1129).\n            actions: ['unsetRefreshToken', 'markExpiredSession'],\n            target: 'unauthenticating',\n            guard: () => typeof window !== 'undefined',\n          },\n          {\n            actions: ['unsetRefreshToken', 'notifyUnauthenticated'],\n            target: 'loggedOut.afterRefreshFailure',\n          },\n        ],\n      },\n    },\n    /**\n     * `loggedOut` is a compound state. The substate records *why* we\n     * are logged out so consumers can react appropriately — most\n     * importantly, so a failed login attempt on an inline auth form\n     * (e.g. /checkout step 1) does not trigger the same hard reload\n     * that a real logout does, which would destroy the form's error\n     * state before the user sees it.\n     *\n     * Transition matrix:\n     *   initializing      → loggedOut.initial              (cold load, no token)\n     *   authenticating    → loggedOut.afterFailedAuth      (wrong password)\n     *   unauthenticating  → loggedOut.afterLogout          (DELIBERATE user logout — logoutReason 'deliberate')\n     *   unauthenticating  → loggedOut.afterRefreshFailure  (client refresh failure — logoutReason 'expired', CTAP-1129)\n     *   refreshing (SSR)  → loggedOut.afterRefreshFailure  (no client window to fall through unauthenticating)\n     *\n     * Existing consumer code that uses `state.matches('loggedOut')`\n     * still matches every substate (xstate parent matching). Code\n     * that uses `state.value === 'loggedOut'` will need to migrate to\n     * `.matches()` because compound `value` is `{ loggedOut: '<sub>' }`.\n     */\n    loggedOut: {\n      initial: 'initial',\n      on: {\n        LOGIN: {\n          target: 'authenticating',\n        },\n        CLEAR_ERRORS: {\n          actions: 'clearErrors',\n        },\n      },\n      states: {\n        initial: {},\n        afterFailedAuth: {},\n        afterLogout: {},\n        afterRefreshFailure: {},\n      },\n    },\n    /**\n     * loggedInReady transient state is a workaround to restoring the snapshot on client side,\n     * since actions won't run (they are assumed to have run already) and timers are stopped (they\n     * have no clock mechanism to determine at what point to restart)\n     */\n    loggedInReady: {\n      on: {\n        RESTORE: {\n          guard: () => typeof window !== 'undefined',\n          target: 'loggedIn',\n        },\n      },\n    },\n    loggedIn: {\n      after: {\n        // 14min (840000ms), jwt access token expires in 15min\n        // 840000: {\n        refresh: {\n          guard: () => typeof window !== 'undefined',\n          target: 'refreshing',\n        },\n      },\n      on: {\n        LOGOUT: {\n          // Deliberate sign-out → mark it so `unauthenticating` routes to\n          // afterLogout (home), distinct from an expired session (CTAP-1129).\n          actions: 'markDeliberateLogout',\n          target: 'unauthenticating',\n        },\n        // A server 401 on an authenticated request: same teardown as LOGOUT,\n        // but marked EXPIRED so the visitor is returned to where they were via\n        // the login page instead of being dropped on the home page (CTAP-1425).\n        SESSION_EXPIRED: {\n          actions: 'markExpiredSession',\n          target: 'unauthenticating',\n        },\n        CLEAR_ERRORS: {\n          actions: 'clearErrors',\n        },\n        LOGIN: {\n          target: 'authenticating',\n        },\n        REFRESH_TOKEN: {\n          target: 'refreshing',\n        },\n        // Stay signed in after an email/password change: swap in the re-issued access token\n        // (self-transition, no re-auth). The rotated refresh cookie was set on the mutation response.\n        // `reenter` matters: a targetless self-transition keeps the REVOKED\n        // token's `after: refresh` schedule, so the first background refresh\n        // after a credential change fired on the old token's clock. Re-entering\n        // restarts the 14-minute timer for the re-issued token (CTAP-1159).\n        SESSION_REISSUED: {\n          actions: ['setReissuedAccessToken', 'notifyReissued'],\n          target: 'loggedIn',\n          reenter: true,\n        },\n        // AFTER_LOGGED_IN: {\n        //   target: 'afterLoggedIn',\n        // },\n      },\n    },\n    // onLogin: {\n    //   always: {\n    //     target: 'loggedIn',\n    //   },\n    // },\n    // afterLoggedOut: {\n    //   always: {\n    //     target: 'loggedOut',\n    //   },\n    // },\n  },\n});\n\nexport default authMachine;\n","'use client';\n\nimport {\n  createContext,\n  useContext,\n  useEffect,\n  useMemo,\n  useState,\n  ReactNode,\n} from 'react';\nimport { Actor, InspectionEvent, Observer, createActor } from 'xstate';\nimport { useSessionTransition } from '../session';\nimport { authMachine } from './auth';\nimport { AuthTransport } from './transport';\n\nexport interface AuthContextType {\n  authActor: Actor<typeof authMachine>;\n  /**\n   * The visitor's identity. Held steady for the duration of a session\n   * transition — see the `AuthProvider` doc block for the two ordering\n   * constraints that hold depends on (it must be mounted inside\n   * `SessionTransitionProvider`, and the gate is `transitionRef`, not\n   * `isTransitioning`).\n   *\n   * This is the ONLY session value published here. \"Is a session change\n   * happening?\" belongs to `useSessionTransition()`, not to auth state.\n   *\n   * There used to be an `isLoggingOut` flag too, derived from\n   * `unauthenticating || loggedOut.afterLogout`. It is deliberately gone:\n   * `afterLogout` is a TERMINAL state, so the flag stayed true for the life of\n   * the actor and wedged everything gated on it — the header account menu became\n   * permanently unclickable, the logout overlay reappeared on unrelated pages,\n   * and the account-page sign-in redirect stopped firing altogether. Every\n   * consumer invented its own escape hatch and none of them held. Removing it\n   * outright is what stops that being reintroduced (CTAP-1151).\n   */\n  isLoggedIn: boolean;\n}\n\n/**\n * Auth state is derived ONCE, here in the provider, and published whole.\n *\n * It used to be derived inside `useAuth()`, which meant every one of ~60 call\n * sites ran its own `useState` + `authActor.subscribe`. Beyond the waste, that\n * made the identity freeze below unsound: a component mounting mid-transition\n * seeded `isLoggedIn` from the LIVE snapshot while its already-mounted siblings\n * were still holding the pre-transition value, so two parts of the same screen\n * disagreed about whether the visitor was signed in. One shared value cannot\n * diverge.\n */\nconst AuthContext = createContext<AuthContextType>({} as AuthContextType);\n\nexport const useAuth = (): AuthContextType => useContext(AuthContext);\n\n// export const useUser = () => {\n//   return useContext(AuthContext).getSnapshot().context.user;\n// };\n\ntype AuthOptions = {\n  inspect: Observer<InspectionEvent> | undefined;\n  endpoints: {\n    login: string;\n    logout: string;\n    refresh: string;\n    ssrRefresh: string;\n  };\n  /** Header injection for the auth HTTP calls — see `./transport`. */\n  transport?: AuthTransport;\n};\n\n/**\n * runs on server side as part of withAuth HOF\n *\n * @todo should probably update signature to pass Partial<AuthContext> and\n * Options, endpoints should probably be moved into context\n */\nexport const getAuth = async (\n  refreshToken = '',\n  options: AuthOptions = {\n    inspect: undefined,\n    endpoints: { login: '', logout: '', refresh: '', ssrRefresh: '' },\n  },\n) => {\n  return createActor(authMachine, {\n    input: {\n      transport: options.transport,\n      initialContext: {\n        endpoints: options.endpoints,\n        refreshToken,\n      },\n    },\n    inspect: options.inspect,\n  }).start();\n};\n\ntype AuthSnapshot = ReturnType<Actor<typeof authMachine>['getSnapshot']>;\n\n/**\n * Signed-in predicate — `loggedIn` OR `loggedInReady`.\n *\n * `loggedInReady` is the rehydration state: an actor restored from a serialized\n * snapshot on the server, authenticated but waiting for the client `RESTORE`\n * event. The visitor genuinely IS signed in there, so it must count.\n *\n * It is easy to miss because it is unreachable in a consumer that prepends the\n * `initializing` state — that short-circuits straight to `loggedIn` whenever a\n * token is present, so `loggedInReady` never occurs and omitting it does no\n * visible harm. Consumers that restore a snapshot through the `withAuth` HOF do\n * reach it, and for them omitting it renders an authenticated visitor as signed\n * out for the whole of hydration.\n */\nconst isSignedIn = (snapshot: AuthSnapshot): boolean =>\n  snapshot.matches('loggedIn') || snapshot.matches('loggedInReady');\n\ntype Props = {\n  actor: Actor<typeof authMachine>;\n  children: ReactNode;\n};\n\n/**\n * Publishes the auth actor and a single derived `isLoggedIn`.\n *\n * ## Two ordering constraints you can get wrong silently\n *\n * **1. `SessionTransitionProvider` MUST be an ancestor of this provider.**\n * `isLoggedIn` is held steady for the duration of a session transition, and that\n * hold is read from `useSessionTransition()`. Mounted outside the transition\n * provider, this reads the inert default context (`transitionRef: {current:\n * false}`) — which is safe rather than throwing, so nothing warns and nothing\n * breaks in an obvious way. The identity simply flips mid-transition anyway: the\n * overlay covers the screen while the checkout swaps to the guest email form\n * underneath it, and the browser offers autofill for the guest email.\n *\n * **2. The hold is gated on `transitionRef`, not `isTransitioning`** — and any\n * consumer mirroring this identity into its own state must do the same.\n * `isTransitioning` is React state, so it only reflects a transition after a\n * re-render, while actor subscriptions fire synchronously on the machine's own\n * transitions and routinely outrun it: a local sign-out reaches `afterLogout`\n * while `isTransitioning` still reads `false`. If you keep a copy of the\n * identity (feeding a router provider, say), the fix is to **delete the mirror\n * and read the held value here** rather than to reproduce the ref gating.\n *\n * ## Why the identity is held but the actor is not\n *\n * The actor freeze in the app's provider tree covers the quote/checkout\n * subtrees, but the auth actor must stay LIVE — components send LOGIN/LOGOUT\n * through it and several subscribe directly, so a frozen proxy would deadlock\n * sign-in. The identity alone is held; transition progress stays live because the\n * overlay renders from it (CTAP-1150/1151).\n */\nexport function AuthProvider({ actor, children }: Props) {\n  const [isLoggedIn, setIsLoggedIn] = useState(() =>\n    isSignedIn(actor.getSnapshot()),\n  );\n\n  // Hold `isLoggedIn` steady while a session transition is in flight.\n  //\n  // The actor freeze in `Providers` covers the quote/checkout subtrees, but the\n  // auth actor must stay LIVE — components send LOGIN/LOGOUT through it and\n  // several subscribe to it directly, so a frozen proxy would deadlock sign-in\n  // and latch `useAuthTransitioning`. So the identity alone is held: without it\n  // the checkout Information step swaps to the guest email form behind the\n  // overlay, which the browser then offers autofill for. The progress signals\n  // below stay live by design — the overlay depends on them.\n  const { isTransitioning, transitionRef } = useSessionTransition();\n\n  useEffect(() => {\n    const subscription = actor.subscribe((snapshot) => {\n      // Gate on the REF, not the state value. This callback runs synchronously\n      // with the machine's transition, which outruns React: a local sign-out\n      // reaches `afterLogout` while `isTransitioning` still reads false, so the\n      // identity would flip mid-freeze.\n      if (!transitionRef.current) {\n        if (isSignedIn(snapshot)) {\n          setIsLoggedIn(true);\n        } else if (snapshot.matches('loggedOut')) {\n          setIsLoggedIn(false);\n        }\n      }\n    });\n\n    return () => {\n      subscription.unsubscribe();\n    };\n  }, [actor, transitionRef]);\n\n  // Re-sync when the freeze lifts. The machine usually settles DURING the\n  // transition, so there is no later emission to carry the final value — the\n  // held update would otherwise be lost and the identity would stay stale until\n  // some unrelated auth event happened to fire.\n  useEffect(() => {\n    if (isTransitioning) {\n      return;\n    }\n    const snapshot = actor.getSnapshot();\n    if (isSignedIn(snapshot)) {\n      // Freeze-lift re-sync from an external store: the machine settled\n      // DURING the transition, so no later emission carries the final value;\n      // this effect is the only place the held identity can catch up\n      // (CTAP-1150/1151). Hence the set-state-in-effect disables.\n      // eslint-disable-next-line react-hooks/set-state-in-effect\n      setIsLoggedIn(true);\n    } else if (snapshot.matches('loggedOut')) {\n      setIsLoggedIn(false);\n    }\n  }, [isTransitioning, actor]);\n\n  const value = useMemo(\n    () => ({ authActor: actor, isLoggedIn }),\n    [actor, isLoggedIn],\n  );\n\n  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n"],"names":["addError","context","event","e","clearErrors","notifyAuthenticated","notifyUnauthenticated","setAccessToken","setIgnoreRefreshToken","setUserContext","unsetRefreshToken","unsetUserContext","AuthMachineStatusCode","DEFAULT_AUTH_HEADERS","resolveAuthHeaders","transport","call","authenticate","fromPromise","input","knownCode","code","fail","cause","error","data","request","err","isDevelopment","IS_SERVER","refreshAccessToken","unauthenticate","authMachine","setup","assign","addErrorAction","clearErrorsAction","emit","notifyAuthenticatedAction","notifyUnauthenticatedAction","setAccessTokenAction","assertEvent","setIgnoreRefreshTokenAction","setUserContextAction","unsetRefreshTokenAction","unsetUserContextAction","authenticateActor","refreshAccessTokenActor","unauthenticateActor","AuthContext","createContext","useAuth","useContext","getAuth","refreshToken","options","createActor","isSignedIn","snapshot","AuthProvider","actor","children","isLoggedIn","setIsLoggedIn","useState","isTransitioning","transitionRef","useSessionTransition","useEffect","subscription","value","useMemo","jsx"],"mappings":"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"}