Files
chad/server/plugins/auth.ts
2026-05-22 05:08:02 +06:00

98 lines
2.1 KiB
TypeScript

import type { Session } from 'lucia'
import { PrismaAdapter } from '@lucia-auth/adapter-prisma'
import fp from 'fastify-plugin'
import { Lucia } from 'lucia'
interface DatabaseUserAttributes {
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<any, DatabaseUserAttributes>(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'],
})