/** * Request-scoped security helpers shared by the route plugins: detect HTTPS (drives the Secure * cookie flag) and read/verify the session cookie off an incoming Fastify request. */ import type { FastifyRequest } from 'fastify' import { parseCookieHeader, SESSION_COOKIE_NAME } from './cookies.js' import { verifySessionToken } from './session.js' /** * True iff the request arrived over HTTPS — directly (`socket.encrypted`) or via a TLS-terminating * edge that set `x-forwarded-proto: https`. Even though the panel binds loopback, a reverse proxy * may front it; honour XFP so the Secure flag is correct on the tunnel path. */ export function isSecureRequest(req: FastifyRequest): boolean { const xfp = req.headers['x-forwarded-proto'] const proto = Array.isArray(xfp) ? xfp[0] : xfp if (typeof proto === 'string' && proto.split(',')[0]?.trim().toLowerCase() === 'https') return true const socket = req.raw.socket as { encrypted?: boolean } | undefined return socket?.encrypted === true } /** True iff the request carries a valid, unexpired session cookie signed with `sessionSecret`. */ export function requestIsAuthed(req: FastifyRequest, sessionSecret: string, nowMs: number): boolean { const cookies = parseCookieHeader(req.headers.cookie) return verifySessionToken(sessionSecret, cookies[SESSION_COOKIE_NAME], nowMs) }