import { FastifyInstance } from "fastify" import bcrypt from "bcrypt" import { eq } from "drizzle-orm" import jwt from "jsonwebtoken" import { secrets } from "../../utils/secrets" import { authUsers } from "../../../db/schema" // wichtig: Drizzle Schema importieren! export default async function authRoutesAuthenticated(server: FastifyInstance) { server.post("/auth/refresh", { schema: { tags: ["Auth"], summary: "Refresh JWT for current authenticated user", response: { 200: { type: "object", properties: { token: { type: "string" }, }, required: ["token"], }, 401: { type: "object", properties: { error: { type: "string" }, }, required: ["error"], }, }, }, }, async (req, reply) => { if (!req.user?.user_id) { return reply.code(401).send({ error: "Unauthorized" }) } const token = jwt.sign( { user_id: req.user.user_id, email: req.user.email, tenant_id: req.user.tenant_id, }, secrets.JWT_SECRET!, { expiresIn: "6h" } ) reply.setCookie("token", token, { path: "/", httpOnly: true, sameSite: process.env.NODE_ENV === "production" ? "none" : "lax", secure: process.env.NODE_ENV === "production", maxAge: 60 * 60 * 6, }) return { token } }) server.post("/auth/password/change", { schema: { tags: ["Auth"], summary: "Change password (after login or forced reset)", body: { type: "object", required: ["old_password", "new_password"], properties: { old_password: { type: "string" }, new_password: { type: "string" }, }, }, response: { 200: { type: "object", properties: { success: { type: "boolean" }, }, }, }, }, }, async (req, reply) => { try { const { old_password, new_password } = req.body as { old_password: string new_password: string } const userId = req.user?.user_id if (!userId) { //@ts-ignore return reply.code(401).send({ error: "Unauthorized" }) } // ----------------------------------------------------- // 1) User laden // ----------------------------------------------------- const [user] = await server.db .select({ id: authUsers.id, passwordHash: authUsers.passwordHash, mustChangePassword: authUsers.must_change_password }) .from(authUsers) .where(eq(authUsers.id, userId)) .limit(1) if (!user) { //@ts-ignore return reply.code(404).send({ error: "User not found" }) } // ----------------------------------------------------- // 2) Altes PW prüfen // ----------------------------------------------------- const valid = await bcrypt.compare(old_password, user.passwordHash) if (!valid) { //@ts-ignore return reply.code(401).send({ error: "Old password incorrect" }) } // ----------------------------------------------------- // 3) Neues PW hashen // ----------------------------------------------------- const newHash = await bcrypt.hash(new_password, 10) // ----------------------------------------------------- // 4) Updaten // ----------------------------------------------------- await server.db .update(authUsers) .set({ passwordHash: newHash, must_change_password: false, updatedAt: new Date(), }) .where(eq(authUsers.id, userId)) return { success: true } } catch (err) { console.error("POST /auth/password/change ERROR:", err) //@ts-ignore return reply.code(500).send({ error: "Internal Server Error" }) } }) }