import type { Session } from 'lucia' import { PrismaAdapter } from '@lucia-auth/adapter-prisma' import fp from 'fastify-plugin' import { Lucia } from 'lucia' interface DatabaseUserAttributes { id: string displayName: string username: string createdAt: Date } declare module 'lucia' { interface Register { Lucia: Lucia UserId: string DatabaseUserAttributes: DatabaseUserAttributes } } declare module 'fastify' { interface FastifyInstance { lucia: Lucia } interface FastifyRequest { user: DatabaseUserAttributes | null session: Session | null } interface FastifyContextConfig { skipAuth: boolean } } export default fp(async (fastify) => { const lucia = new Lucia(new PrismaAdapter(fastify.prisma.session, fastify.prisma.user), { sessionCookie: { attributes: { sameSite: 'none', }, }, getUserAttributes: (attrs) => { return attrs }, }) fastify.decorate('lucia', lucia) fastify.decorateRequest('user', null) fastify.decorateRequest('session', null) fastify.addHook('onRequest', async (req, reply) => { try { const sessionId = lucia.readSessionCookie(req.headers.cookie ?? '') if (!sessionId) return const { session, user } = await lucia.validateSession(sessionId ?? '') if (session && session.fresh) { const cookie = lucia.createSessionCookie(session.id) reply.setCookie(cookie.name, cookie.value, cookie.attributes) } if (!session) { const blank = lucia.createBlankSessionCookie() reply.setCookie(blank.name, blank.value, blank.attributes) } req.user = user as DatabaseUserAttributes req.session = session } catch { req.user = null req.session = null } }) fastify.addHook('onRequest', (req, reply, done) => { if (req.is404 || req.routeOptions.schema?.hide || req.routeOptions.config.skipAuth) { done() return } if (!req.user) { reply.unauthorized() } done() }) }, { name: 'auth', dependencies: ['prisma'], })