{"version":3,"file":"utils-KaM5VMTJ.mjs","names":["OFFLINE_USER_KEY","OFFLINE_PHOTO_KEY","GRACE_PERIOD","Cached","value","T","savedAt","recall","key","localStorage","raw","getItem","JSON","parse","Date","now","removeItem","remember","undefined","setItem","stringify","isOfflineFailure","error","navigator","onLine","TypeError","withOfflineFallback","fetchFresh","Promise","fresh","clearSessionSnapshot","String","window","addEventListener","event","location","href","createEnv","z","clientEnv","clientPrefix","client","runtimeEnv","import","meta","env","emptyStringAsUndefined","serverEnv","server","ENTRA_CLIENT_ID","string","min","ENTRA_TENANT_ID","ENTRA_CLIENT_SECRET","AWS_ISSUER","url","optional","AWS_DOMAIN","AWS_CLIENT_ID","AWS_CLIENT_SECRET","SESSION_SECRET","FILE_BASE_URL","APPROVAL_BASE_URL","PEOPLESOFT_BASE_URL","EMAIL_BASE_URL","AI_BASE_URL","AI_SUBSCRIPTION_KEY","process","useSession","serverEnv","ProviderId","User","AppSessionData","provider","refreshToken","user","pkceVerifier","state","returnTo","AppSession","Awaited","ReturnType","getAppSession","Promise","getSession","name","password","SESSION_SECRET","queryOptions","createServerFn","QueryClientParam","ProviderId","User","OFFLINE_USER_KEY","withOfflineFallback","getAppSession","getSessionUser","method","handler","Promise","session","data","user","getLoginProviders","Array","id","label","providers","map","loginProvidersQueryOptions","queryKey","queryFn","staleTime","userQueryOptions","Infinity","networkMode","refetchOnReconnect","getUser","queryClient","import","meta","env","SSR","ensureQueryData","AnyFieldApi","redirect","ParsedLocation","manifest","permissions","QueryClientParam","TokenPayload","ProviderId","User","getUser","WISTRON_PRIMARY_COLOR","WISTRON_SECONDARY_COLOR","Platform","isAndroid","test","userAgent","isIOS","isWindows","isMacOS","navigator","RootRouteHeadOptions","rootRouteHead","options","meta","charSet","name","content","title","links","rel","sizes","href","type","GuardArgs","location","context","requireAuth","permissionKey","user","queryClient","encodeURIComponent","reloadDocument","hasPermission","Error","NON_PRODUCTION","isTestEnv","origin","split","slice","join","FormOmittedProps","getFieldStatus","field","state","isTouched","hasError","errors","length","helperText","message","sanitizeReturnTo","value","toKebabCase","str","replaceAll","toLowerCase","foldForSearch","String","normalize","permissionGroups","Set","Object","values","flat","buildUser","payload","provider","email","preferred_username","department","toUpperCase","employeeId","companyName","groups","filter","group","has","key","some","includes"],"sources":["../src/lib/auth/offline.ts","../src/env.ts","../src/lib/auth/session.ts","../src/lib/auth/user.ts","../src/lib/utils.ts"],"sourcesContent":["/**\n * Offline fallback for identity. The refresh token never leaves the sealed\n * httpOnly cookie — what is cached here is only the display snapshot (user\n * claims and avatar) so the UI and offline route permissions can still work\n * while the server is unreachable. Server requests remain independently\n * authorized. At-rest protection is the device's OS login and disk encryption.\n */\n\nexport const OFFLINE_USER_KEY = \"auth-user\";\nexport const OFFLINE_PHOTO_KEY = \"auth-photo\";\n\n/** One shift — matches Intune's default offline grace period. */\nconst GRACE_PERIOD = 12 * 60 * 60 * 1000;\n\ntype Cached<T> = { value: T; savedAt: number };\n\nconst recall = <T>(key: string): T | null => {\n  if (typeof localStorage === \"undefined\") return null;\n  try {\n    const raw = localStorage.getItem(key);\n    if (!raw) return null;\n    const { value, savedAt } = JSON.parse(raw) as Cached<T>;\n    if (Date.now() - savedAt > GRACE_PERIOD) {\n      localStorage.removeItem(key);\n      return null;\n    }\n    return value;\n  } catch {\n    localStorage.removeItem(key);\n    return null;\n  }\n};\n\nconst remember = (key: string, value: unknown): void => {\n  if (typeof localStorage === \"undefined\") return;\n  try {\n    if (value === null || value === undefined) localStorage.removeItem(key);\n    else localStorage.setItem(key, JSON.stringify({ value, savedAt: Date.now() }));\n  } catch {\n    // Storage full or blocked — the offline fallback is best-effort.\n  }\n};\n\nconst isOfflineFailure = (error: unknown): boolean =>\n  (typeof navigator !== \"undefined\" && !navigator.onLine) || error instanceof TypeError;\n\n/**\n * Answers from the server when reachable, remembering the result; when the call\n * has a transport failure, replays the last result instead, for up to\n * {@link GRACE_PERIOD} since it was last confirmed.\n *\n * Cached values are untrusted client state. Server authorization must never\n * depend on them.\n */\nexport const withOfflineFallback = async <T>(\n  key: string,\n  fetchFresh: () => Promise<T>,\n): Promise<T | null> => {\n  try {\n    const fresh = await fetchFresh();\n    remember(key, fresh);\n    return fresh;\n  } catch (error) {\n    if (!isOfflineFailure(error)) throw error;\n    return recall<T>(key);\n  }\n};\n\n/** Drops the cached identity. Call on logout, before leaving the page. */\nexport const clearSessionSnapshot = (): void => {\n  if (typeof localStorage === \"undefined\") return;\n  localStorage.removeItem(OFFLINE_USER_KEY);\n  localStorage.removeItem(OFFLINE_PHOTO_KEY);\n  localStorage.setItem(\"auth-logout\", String(Date.now()));\n};\n\nif (typeof window !== \"undefined\")\n  window.addEventListener(\"storage\", (event) => {\n    if (event.key === \"auth-logout\") location.href = \"/auth/logout\";\n  });\n","import { createEnv } from \"@t3-oss/env-core\";\nimport { z } from \"zod\";\n\nexport const clientEnv = createEnv({\n  clientPrefix: \"VITE_\",\n  client: {},\n  runtimeEnv: import.meta.env,\n  emptyStringAsUndefined: true,\n});\n\nexport const serverEnv = createEnv({\n  server: {\n    ENTRA_CLIENT_ID: z.string().min(1),\n    ENTRA_TENANT_ID: z.string().min(1),\n    ENTRA_CLIENT_SECRET: z.string().min(1),\n    AWS_ISSUER: z.url().optional(),\n    AWS_DOMAIN: z.url().optional(),\n    AWS_CLIENT_ID: z.string().min(1).optional(),\n    AWS_CLIENT_SECRET: z.string().min(1).optional(),\n    SESSION_SECRET: z.string().min(32),\n    FILE_BASE_URL: z.string().min(1).optional(),\n    APPROVAL_BASE_URL: z.string().min(1).optional(),\n    PEOPLESOFT_BASE_URL: z.string().min(1).optional(),\n    EMAIL_BASE_URL: z.string().min(1).optional(),\n    AI_BASE_URL: z.string().min(1).optional(),\n    AI_SUBSCRIPTION_KEY: z.string().min(1).optional(),\n  },\n  runtimeEnv: process.env,\n  emptyStringAsUndefined: true,\n});\n","import type { useSession } from \"@tanstack/react-start/server\";\r\nimport { serverEnv } from \"~/env\";\r\nimport type { ProviderId, User } from \"~/models/User\";\r\n\r\nexport interface AppSessionData {\r\n  /** Which identity provider signed this user in. */\r\n  provider?: ProviderId;\r\n  /** The only token persisted; delegated access tokens are minted from it. */\r\n  refreshToken?: string;\r\n  user?: User;\r\n  /** Transient, only between /auth/login and /auth/callback. */\r\n  pkceVerifier?: string;\r\n  state?: string;\r\n  returnTo?: string;\r\n}\r\n\r\n/** `SessionManager` is not re-exported upstream, so name it through `useSession`. */\r\nexport type AppSession = Awaited<ReturnType<typeof useSession<AppSessionData>>>;\r\n\r\nexport const getAppSession = async (): Promise<AppSession> => {\r\n  // Dynamic import: `@tanstack/react-start/server` is the server entry and drags\r\n  // in the SSR renderer (`react-dom/server`). Keep it out of the client graph —\r\n  // this helper is only ever called server-side, and all callers already await it.\r\n  // Aliased off the `use*` name so it isn't mistaken for a React hook (it's a\r\n  // server session helper, not a hook).\r\n  const { useSession: getSession } = await import(\"@tanstack/react-start/server\");\r\n\r\n  return getSession<AppSessionData>({\r\n    name: \"session\",\r\n    password: serverEnv.SESSION_SECRET,\r\n  });\r\n};\r\n","import { queryOptions } from \"@tanstack/react-query\";\nimport { createServerFn } from \"@tanstack/react-start\";\nimport type { QueryClientParam } from \"~/models/QueryClientParam\";\nimport type { ProviderId, User } from \"~/models/User\";\nimport { OFFLINE_USER_KEY, withOfflineFallback } from \"./offline\";\nimport { getAppSession } from \"./session\";\n\n/**\n * Reads the signed-in user from the session cookie, or null. As a server function\n * it runs in-process when called on the server (SSR, middleware) and as an RPC\n * when called from the client — so it doubles as the client `queryFn`.\n */\nexport const getSessionUser = createServerFn({ method: \"GET\" }).handler(\n  async (): Promise<User | null> => {\n    const session = await getAppSession();\n    return session.data.user ?? null;\n  },\n);\n\n/** The identity providers the server offers, for the login page. */\nexport const getLoginProviders = createServerFn({ method: \"GET\" }).handler(\n  async (): Promise<Array<{ id: ProviderId; label: string }>> => {\n    // Dynamic import: `providers` reads `serverEnv` and must not reach the client.\n    const { providers } = await import(\"./providers\");\n    return providers.map(({ id, label }) => ({ id, label }));\n  },\n);\n\n/**\n * Feeds `LoginForm`. Server config, not per-user, so it is safe to prime on the\n * server — the `/login` route's loader does that to avoid a flash of empty card.\n */\nexport const loginProvidersQueryOptions = queryOptions({\n  queryKey: [\"auth\", \"providers\"],\n  queryFn: () => getLoginProviders(),\n  staleTime: \"static\",\n});\n\n/**\n * Client-side query for the signed-in user. Shared between `getUser` (route\n * `beforeLoad`) and the always-mounted observer in `LayoutProvider` — the\n * observer is what seeds the offline snapshot on the very first page load\n * (`beforeLoad` does not re-run after SSR hydration) and what makes\n * `refetchOnReconnect` fire once connectivity returns.\n */\nexport const userQueryOptions = queryOptions({\n  queryKey: [\"auth\", \"user\"],\n  queryFn: () => withOfflineFallback(OFFLINE_USER_KEY, () => getSessionUser()),\n  staleTime: Infinity,\n  // Default \"online\" pauses the query (never calling queryFn) once the browser\n  // reports no connection — which is exactly when the fallback is needed.\n  networkMode: \"offlineFirst\",\n  // Back online: re-confirm the session and re-stamp the snapshot's grace period.\n  refetchOnReconnect: \"always\",\n});\n\nexport const getUser = ({ queryClient }: QueryClientParam): Promise<User | null> => {\n  if (import.meta.env.SSR) return getSessionUser();\n\n  return queryClient.ensureQueryData(userQueryOptions);\n};\n","import type { AnyFieldApi } from \"@tanstack/react-form\";\nimport { redirect } from \"@tanstack/react-router\";\nimport type { ParsedLocation } from \"@tanstack/react-router\";\nimport { manifest, permissions } from \"virtual:wcz-layout\";\nimport type { QueryClientParam } from \"~/models/QueryClientParam\";\nimport type { TokenPayload } from \"~/models/TokenPayload\";\nimport type { ProviderId, User } from \"~/models/User\";\nimport { getUser } from \"./auth/user\";\n\nexport const WISTRON_PRIMARY_COLOR = \"#00506E\";\nexport const WISTRON_SECONDARY_COLOR = \"#64DC00\";\n\nexport class Platform {\n  static get isAndroid() {\n    return /android/i.test(this.userAgent);\n  }\n  static get isIOS() {\n    return /iPad|iPhone|iPod/.test(this.userAgent);\n  }\n  static get isWindows() {\n    return /windows/i.test(this.userAgent);\n  }\n  static get isMacOS() {\n    return /Macintosh|MacIntel|MacPPC|Mac68K/.test(this.userAgent);\n  }\n\n  private static get userAgent() {\n    return typeof navigator === \"undefined\" ? \"\" : navigator.userAgent;\n  }\n}\n\ninterface RootRouteHeadOptions {\n  manifest?: string;\n}\n\nexport const rootRouteHead = (options?: RootRouteHeadOptions) => ({\n  meta: [\n    { charSet: \"utf-8\" },\n    { name: \"viewport\", content: \"width=device-width, initial-scale=1\" },\n    { title: manifest.name },\n    { name: \"og:type\", content: \"website\" },\n    { name: \"og:title\", content: manifest.name },\n    { name: \"og:image\", content: \"/favicon-32x32.png\" },\n  ],\n  links: [\n    { rel: \"apple-touch-icon\", sizes: \"180x180\", href: \"/apple-touch-icon.png\" },\n    { rel: \"icon\", type: \"image/png\", sizes: \"32x32\", href: \"/favicon-32x32.png\" },\n    { rel: \"icon\", type: \"image/png\", sizes: \"16x16\", href: \"/favicon-16x16.png\" },\n    { rel: \"manifest\", href: options?.manifest || \"/manifest.json\" },\n    { rel: \"icon\", href: \"/favicon.ico\" },\n  ],\n});\n\ntype GuardArgs = { location: ParsedLocation; context: QueryClientParam };\n\n/**\n * Route guard for `beforeLoad`. Routes are public by default; add this to close one.\n *\n * - `requireAuth()` — signed in with any provider. The only gate a population\n *   without permission groups (e.g. AWS users) can pass.\n * - `requireAuth(\"admin\")` — signed in *and* in a group listed under that key.\n *\n * `reloadDocument` is required: `/auth/login` is a component-less server route and\n * must be reached with a full-document navigation. It starts the login directly when\n * only one provider is registered, otherwise it forwards to the `/login` chooser.\n */\nexport const requireAuth = (permissionKey?: keyof typeof permissions) => {\n  return async ({ location, context }: GuardArgs) => {\n    const user = await getUser({ queryClient: context.queryClient });\n\n    if (!user)\n      throw redirect({\n        href: `/auth/login?returnTo=${encodeURIComponent(location.href)}`,\n        reloadDocument: true,\n      });\n\n    if (permissionKey && !hasPermission(user, permissionKey))\n      throw new Error(\"You do not have permission to access this page.\");\n\n    return { user };\n  };\n};\n\n/* Internal Utils */\nconst NON_PRODUCTION = /(?:^|[.-])(?:dev|qas|uat|test)(?:[.-]|$)/i;\n\n/** True only for a dev/qas/uat/test domain — localhost and production are not. */\nexport const isTestEnv = (origin: string | undefined) =>\n  NON_PRODUCTION.test((origin ?? \"\").split(\".\").slice(1).join(\".\"));\n\nexport type FormOmittedProps =\n  | \"name\"\n  | \"value\"\n  | \"onChange\"\n  | \"onBlur\"\n  | \"error\"\n  | \"helperText\"\n  | \"renderInput\"\n  | \"type\"\n  | \"aria-label\";\n\nexport const getFieldStatus = (field: AnyFieldApi) => {\n  const { meta } = field.state;\n\n  const isTouched = meta.isTouched;\n  const hasError = !!meta.errors.length;\n  const helperText = meta.errors[0]?.message;\n\n  return { isTouched, hasError, helperText };\n};\n\n/**\n * Only same-origin paths are allowed, so `returnTo` cannot become an open\n * redirect. Backslash counts as a separator too: browsers normalize `/\\evil`\n * to the protocol-relative `//evil`.\n */\nexport const sanitizeReturnTo = (value: string | null | undefined): string =>\n  value && /^\\/(?![/\\\\])/.test(value) ? value : \"/\";\n\nexport const toKebabCase = (str: string): string => {\n  return str\n    .replaceAll(/([a-z])([A-Z])/g, \"$1-$2\")\n    .replaceAll(/[\\s_]+/g, \"-\")\n    .replaceAll(/[^a-zA-Z0-9-]/g, \"\")\n    .toLowerCase()\n    .replaceAll(/-+/g, \"-\")\n    .replaceAll(/(^-|-$)/g, \"\");\n};\n\nexport const foldForSearch = (value: unknown): string =>\n  String(value ?? \"\")\n    .toLowerCase()\n    .normalize(\"NFD\")\n    .replaceAll(/[\\u{300}-\\u{36F}]/gu, \"\")\n    .normalize(\"NFC\");\n\nconst permissionGroups = new Set<string>(Object.values(permissions).flat());\n\n/**\n * Maps id/access-token claims to the serializable `User`. Groups are trimmed to\n * those named in `permissions.ts` — an unfiltered group list would blow the\n * cookie. Cognito's claim names differ, so both are read.\n */\nexport const buildUser = (payload: TokenPayload, provider: ProviderId): User => ({\n  provider,\n  name: (payload.name ?? payload[\"cognito:username\"] ?? \"\").split(\"/\")[0],\n  email: (payload.preferred_username ?? payload.email ?? \"\").toLowerCase(),\n  department: payload.department?.toUpperCase() || \"\",\n  employeeId: (payload.employeeId ?? payload[\"cognito:username\"] ?? \"\").toUpperCase(),\n  companyName: payload.companyName || \"\",\n  groups:\n    (payload.groups ?? payload[\"cognito:groups\"])?.filter((group) => permissionGroups.has(group)) ??\n    [],\n});\n\nexport const hasPermission = (user: User | null, key: keyof typeof permissions): boolean =>\n  user ? permissions[key].some((group) => user.groups.includes(group)) : false;\n"],"mappings":"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"}