import type { UserRole } from './types' const AUTH_COOKIE = 'balout.auth' const AUTH_HASH_PREFIX = '#balout_auth=' export type AuthUser = { id: string title: string firstName: string lastName: string cellNumber: string role: UserRole name: string } export type AuthSession = { accessToken: string refreshToken: string user: AuthUser } function isSession(value: unknown): value is AuthSession { if (!value || typeof value !== 'object') return false const session = value as Partial return ( typeof session.accessToken === 'string' && typeof session.refreshToken === 'string' && !!session.user && typeof session.user === 'object' && typeof session.user.name === 'string' && typeof session.user.id === 'string' ) } function cookieDomain() { const host = window.location.hostname if (host === 'localhost' || host === '127.0.0.1') return undefined const configured = import.meta.env.VITE_COOKIE_DOMAIN as string | undefined if (configured) return configured if (host.endsWith('.baloutpastry.com') || host === 'baloutpastry.com') { return '.baloutpastry.com' } return undefined } function readCookie(name: string) { const prefix = `${encodeURIComponent(name)}=` for (const part of document.cookie.split(';')) { const trimmed = part.trim() if (trimmed.startsWith(prefix)) { return decodeURIComponent(trimmed.slice(prefix.length)) } } return null } function writeCookie(name: string, value: string, maxAgeSeconds: number) { const domain = cookieDomain() const parts = [ `${encodeURIComponent(name)}=${encodeURIComponent(value)}`, 'Path=/', `Max-Age=${maxAgeSeconds}`, 'SameSite=Lax', ] if (domain) parts.push(`Domain=${domain}`) document.cookie = parts.join('; ') } function clearCookie(name: string) { const domain = cookieDomain() const parts = [ `${encodeURIComponent(name)}=`, 'Path=/', 'Max-Age=0', 'SameSite=Lax', ] if (domain) parts.push(`Domain=${domain}`) document.cookie = parts.join('; ') } export function getSession(): AuthSession | null { try { const raw = readCookie(AUTH_COOKIE) if (!raw) return null const parsed = JSON.parse(raw) as unknown return isSession(parsed) ? parsed : null } catch { return null } } export function setSession(session: AuthSession) { writeCookie(AUTH_COOKIE, JSON.stringify(session), 60 * 60 * 24 * 7) } export function clearSession() { clearCookie(AUTH_COOKIE) } export function getAuthUser(): AuthUser | null { return getSession()?.user ?? null } export function getAccessToken(): string | null { return getSession()?.accessToken ?? null } export function isAuthenticated(): boolean { return getSession() !== null } /** Import session handed off from customer login via URL hash. */ export function consumeAuthHashFromUrl() { const hash = window.location.hash if (!hash.startsWith(AUTH_HASH_PREFIX)) return false try { const raw = decodeURIComponent(hash.slice(AUTH_HASH_PREFIX.length)) const parsed = JSON.parse(raw) as unknown if (isSession(parsed)) { setSession(parsed) return true } } catch { // ignore malformed payload } finally { const clean = `${window.location.pathname}${window.location.search}` window.history.replaceState(null, '', clean) } return false } export function getCustomerAppUrl() { return ( (import.meta.env.VITE_CUSTOMER_APP_URL as string | undefined)?.replace(/\/$/, '') || 'http://customer.baloutpastry.com:5173' ) } export function getCustomerLoginUrl(returnUrl = window.location.origin + '/') { const url = new URL(`${getCustomerAppUrl()}/login`) url.searchParams.set('returnUrl', returnUrl) return url.toString() } export function getCustomerDashboardUrl(path = '/') { const base = getCustomerAppUrl() return `${base}${path.startsWith('/') ? path : `/${path}`}` } export function displayName(user: AuthUser) { const short = [user.firstName, user.lastName].filter(Boolean).join(' ').trim() return short || user.name }