import { FreshContext } from '$fresh/server.ts' import { SessionStore } from ':src/session/mod.ts' import { getCookies, setCookie } from '@std/http/cookie' export async function handler(request: Request, ctx: FreshContext) { // Update fresh context state with session ctx.state = { ...ctx.state, session: SessionStore.getFromRequest(request) } // Get response const response = await ctx.next() //Add security headers // See https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/TLS#http_strict_transport_security response.headers.set('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload') response.headers.set('Content-Security-Policy', "frame-ancestors 'none'; upgrade-insecure-requests") //See https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/Referrer_policy response.headers.set('Referrer-Policy', 'no-referrer, strict-origin-when-cross-origin') //See https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/MIME_types response.headers.set('X-Content-Type-Options', 'nosniff') //See https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/Clickjacking response.headers.set('X-Frame-Options', 'DENY') //See https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/CORP response.headers.set('Cross-Origin-Resource-Policy', 'same-origin') //See https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity //? SRI plugin for non local resources only ? //See https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/CSP //? fresh useCSP https://fresh.deno.dev/docs/examples/using-csp // Allow service worker to serve root scope if (ctx.url.pathname.endsWith('island-startserviceworker.js')) { response.headers.set('Service-Worker-Allowed', '/') } // Start session if (SessionStore.getFromRequest(request) === undefined) { // Clear outdated cookies for (const cookie in getCookies(request.headers)) { setCookie(response.headers, { name: cookie, value: '', path: '/', expires: 0, }) } // Create new session const session = SessionStore.createSession() ctx.state = { ...ctx.state, session } // Set session cookie setCookie(response.headers, { name: '__Secure-SESSION', value: session.uuid, httpOnly: true, sameSite: 'Strict', secure: true, path: '/', expires: SessionStore.maxAge, }) // Set csrf const csrf = crypto.randomUUID() session.set('_csrf', csrf) setCookie(response.headers, { name: '__Host-CSRF', value: csrf, httpOnly: false, sameSite: 'Strict', secure: true, path: '/', expires: SessionStore.maxAge, }) } return response }