initial project setup

Fastify + Prisma backend, React + Vite frontend, Docker deployment.
Multi-board feedback platform with anonymous cookie auth, passkey
upgrade path, ALTCHA spam protection, plugin system, and full
privacy-first architecture.
This commit is contained in:
2026-03-19 18:05:16 +02:00
commit f07eddf29e
77 changed files with 7031 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
import { FastifyInstance } from "fastify";
import { PrismaClient } from "@prisma/client";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import { z } from "zod";
import { config } from "../../config.js";
const prisma = new PrismaClient();
const loginBody = z.object({
email: z.string().email(),
password: z.string().min(1),
});
export default async function adminAuthRoutes(app: FastifyInstance) {
app.post<{ Body: z.infer<typeof loginBody> }>(
"/admin/login",
async (req, reply) => {
const body = loginBody.parse(req.body);
const admin = await prisma.adminUser.findUnique({ where: { email: body.email } });
if (!admin) {
reply.status(401).send({ error: "Invalid credentials" });
return;
}
const valid = await bcrypt.compare(body.password, admin.passwordHash);
if (!valid) {
reply.status(401).send({ error: "Invalid credentials" });
return;
}
const token = jwt.sign(
{ sub: admin.id, type: "admin" },
config.JWT_SECRET,
{ expiresIn: "24h" }
);
reply.send({ token });
}
);
}