| 1 | import type { Context } from "hono"; |
| 2 | import { getCookie, setCookie, deleteCookie } from "hono/cookie"; |
| 3 | import type { AppEnv } from "../env"; |
| 4 | import { SESSION_COOKIE, SESSION_TTL_MS } from "../config"; |
| 5 | |
| 6 | // Secure cookies are dropped over plain http, so honour the request scheme: |
| 7 | // https in production, http under `wrangler dev` on localhost. |
| 8 | function isSecure(c: Context<AppEnv>): boolean { |
| 9 | return new URL(c.req.url).protocol === "https:"; |
| 10 | } |
| 11 | |
| 12 | export function readSessionToken(c: Context<AppEnv>): string | undefined { |
| 13 | return getCookie(c, SESSION_COOKIE); |
| 14 | } |
| 15 | |
| 16 | export function setSessionCookie(c: Context<AppEnv>, token: string): void { |
| 17 | const domain = c.env.COOKIE_DOMAIN?.trim(); |
| 18 | setCookie(c, SESSION_COOKIE, token, { |
| 19 | httpOnly: true, |
| 20 | secure: isSecure(c), |
| 21 | sameSite: "Lax", |
| 22 | path: "/", |
| 23 | maxAge: Math.floor(SESSION_TTL_MS / 1000), |
| 24 | ...(domain ? { domain } : {}), |
| 25 | }); |
| 26 | } |
| 27 | |
| 28 | export function clearSessionCookie(c: Context<AppEnv>): void { |
| 29 | const domain = c.env.COOKIE_DOMAIN?.trim(); |
| 30 | deleteCookie(c, SESSION_COOKIE, { |
| 31 | path: "/", |
| 32 | secure: isSecure(c), |
| 33 | ...(domain ? { domain } : {}), |
| 34 | }); |
| 35 | } |
| 36 |