feat: add JWT auth with db-backed users
Some checks failed
Build & Release / build (push) Has been cancelled
Some checks failed
Build & Release / build (push) Has been cancelled
- users table created on startup via migrate() - POST /api/auth/setup to create first user (blocked once any user exists) - POST /api/auth/login returns httpOnly JWT cookie (7d expiry) - POST /api/auth/logout clears cookie - GET /api/auth/me for auth check - All /api/customers routes require valid JWT - Frontend shows login form when unauthenticated - Fix type errors in k8s, do, and pgbouncer services
This commit is contained in:
38
src/index.ts
38
src/index.ts
@@ -1,10 +1,35 @@
|
||||
import Fastify from "fastify";
|
||||
import Fastify, { type FastifyRequest, type FastifyReply } from "fastify";
|
||||
import jwtPlugin from "@fastify/jwt";
|
||||
import cookiePlugin from "@fastify/cookie";
|
||||
|
||||
declare module "fastify" {
|
||||
interface FastifyInstance {
|
||||
authenticate: (req: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
||||
}
|
||||
}
|
||||
import staticFiles from "@fastify/static";
|
||||
import { join } from "path";
|
||||
import { config } from "./lib/config";
|
||||
import { migrate } from "./db/manager";
|
||||
import { authRoutes } from "./routes/auth";
|
||||
import { customerRoutes } from "./routes/customers";
|
||||
|
||||
const app = Fastify({ logger: true });
|
||||
|
||||
await app.register(cookiePlugin);
|
||||
await app.register(jwtPlugin, {
|
||||
secret: config.jwtSecret,
|
||||
cookie: { cookieName: "token", signed: false },
|
||||
});
|
||||
|
||||
app.decorate("authenticate", async function (req: any, reply: any) {
|
||||
try {
|
||||
await req.jwtVerify({ onlyCookie: true });
|
||||
} catch {
|
||||
reply.status(401).send({ message: "Unauthorized" });
|
||||
}
|
||||
});
|
||||
|
||||
app.register(staticFiles, {
|
||||
root: join(import.meta.dir, "../frontend"),
|
||||
prefix: "/",
|
||||
@@ -12,9 +37,16 @@ app.register(staticFiles, {
|
||||
|
||||
app.get("/health", async () => ({ status: "ok" }));
|
||||
|
||||
app.register(customerRoutes, { prefix: "/api" });
|
||||
app.register(authRoutes, { prefix: "/api" });
|
||||
|
||||
app.listen({ port: Number(process.env.PORT ?? 3000), host: "0.0.0.0" }, (err) => {
|
||||
app.register(customerRoutes, {
|
||||
prefix: "/api",
|
||||
onRequest: [app.authenticate],
|
||||
} as any);
|
||||
|
||||
await migrate();
|
||||
|
||||
app.listen({ port: config.port, host: "0.0.0.0" }, (err) => {
|
||||
if (err) {
|
||||
app.log.error(err);
|
||||
process.exit(1);
|
||||
|
||||
Reference in New Issue
Block a user