98 lines
2.1 KiB
TypeScript
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'],
|
|
})
|