/** * Nest httpOnly refresh-cookie names. Keep in lockstep with * `backend/src/modules/auth/auth-cookie.ts`. * * Production HTTPS uses `__Host-` (Secure, host-only, path `/`). * Local HTTP uses the unprefixed name because browsers reject `__Host-` * without the Secure attribute. */ export const REFRESH_TOKEN_COOKIE_HOST = '__Host-ghabilee_refresh' export const REFRESH_TOKEN_COOKIE_DEV = 'ghabilee_refresh' /** Same-origin Next route that expires the Nest httpOnly refresh cookies. */ export const CLEAR_REFRESH_SESSION_PATH = '/api/auth/clear-session' export const CLEAR_REFRESH_SESSION_HEADER = 'x-ghabilee-logout' /** True when the request carries a Nest-issued httpOnly refresh session. */ export const hasRefreshSessionCookie = (getCookie: (name: string) => { value: string } | undefined): boolean => Boolean(getCookie(REFRESH_TOKEN_COOKIE_HOST)?.value || getCookie(REFRESH_TOKEN_COOKIE_DEV)?.value) const EXPIRED_COOKIE = 'Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/; HttpOnly; SameSite=Lax' /** * `Set-Cookie` headers that expire both Nest refresh names. * Two lines for `ghabilee_refresh` (Secure and not) because Next's cookie map * keeps one entry per name, and a Secure cookie will not overwrite an HTTP one. */ export const expiredRefreshSessionSetCookieHeaders = (): string[] => [ `${REFRESH_TOKEN_COOKIE_DEV}=; ${EXPIRED_COOKIE}`, `${REFRESH_TOKEN_COOKIE_DEV}=; ${EXPIRED_COOKIE}; Secure`, `${REFRESH_TOKEN_COOKIE_HOST}=; ${EXPIRED_COOKIE}; Secure`, ]