brf/server/server.ts
2025-12-18 07:31:37 +01:00

71 lines
2.0 KiB
TypeScript

import fastify, { type FastifyServerOptions } from 'fastify'
import fcookie from '@fastify/cookie'
import fsession from '@fastify/session'
import fstatic from '@fastify/static'
import RedisStore from 'fastify-session-redis-store'
import { Redis } from 'ioredis'
import StatusError from './lib/status_error.ts'
import env from './env.ts'
import ErrorHandler from './handlers/error.ts'
import authPlugin from './plugins/auth.ts'
import vitePlugin from './plugins/vite.ts'
import apiRoutes from './routes/api.ts'
import templateAdmin from './templates/admin.ts'
import templatePublic from './templates/public.ts'
export default async (options?: FastifyServerOptions) => {
const server = fastify(options)
server.register(fcookie)
server.register(fsession, {
cookie: {
secure: env.NODE_ENV !== 'development',
maxAge: 24 * 60 * 60 * 1000,
},
cookieName: 'sessionId',
secret: env.SESSION_SECRET,
store: env.NODE_ENV !== 'testing' ? new RedisStore({ client: new Redis(env.REDIS_HOST) }) : undefined,
})
server.setNotFoundHandler(() => {
throw new StatusError(404)
})
server.register(fstatic, {
root: new URL('../uploads', import.meta.url),
prefix: '/uploads/',
})
if (env.NODE_ENV !== 'testing') {
server.register(vitePlugin, {
mode: env.NODE_ENV,
createErrorHandler: ErrorHandler,
entries: {
public: {
path: '/',
template: templatePublic,
},
admin: {
path: '/admin',
template: templateAdmin,
createPreHandler(route) {
return async function preHandler(request, reply) {
if (request.session.userId) {
return (reply.ctx = { user: await request.user })
} else if (route.auth) {
return reply.redirect('/admin/login')
}
}
},
},
},
})
}
server.register(authPlugin, { prefix: '/auth' })
server.register(apiRoutes, { prefix: '/api' })
return server
}