import express from "express"; import bcrypt from "bcryptjs"; import jwt from "jsonwebtoken"; import { JWT_SECRET, authMiddleware } from "../middleware/auth.js"; import { createUser, getUserByUsername, getUserById } from "../db/usersDb.js"; const router = express.Router(); function issueToken(user) { return jwt.sign( { userId: user.id, username: user.username, team: user.team, role: user.role }, JWT_SECRET, { expiresIn: "7d" } ); } // POST /api/auth/register router.post("/register", async (req, res) => { const { username, email, password, team } = req.body ?? {}; if (!username || !email || !password || !team) { return res.status(400).json({ error: "missing_fields" }); } if (team !== "blue" && team !== "red") { return res.status(400).json({ error: "invalid_team" }); } if (typeof username !== "string" || username.length < 2 || username.length > 32) { return res.status(400).json({ error: "invalid_username" }); } if (typeof password !== "string" || password.length < 6) { return res.status(400).json({ error: "password_too_short" }); } try { const passwordHash = await bcrypt.hash(password, 12); const user = await createUser(username.trim(), email.trim().toLowerCase(), passwordHash, team); const token = issueToken(user); return res.status(201).json({ token, user: { id: user.id, username: user.username, team: user.team, role: user.role }, }); } catch (e) { if (e.code === "23505") { if (e.constraint?.includes("email")) return res.status(409).json({ error: "email_taken" }); return res.status(409).json({ error: "username_taken" }); } console.error(e); return res.status(500).json({ error: "database_error" }); } }); // POST /api/auth/login router.post("/login", async (req, res) => { const { username, password } = req.body ?? {}; if (!username || !password) return res.status(400).json({ error: "missing_fields" }); try { const user = await getUserByUsername(username.trim()); if (!user) return res.status(401).json({ error: "invalid_credentials" }); const valid = await bcrypt.compare(password, user.password_hash); if (!valid) return res.status(401).json({ error: "invalid_credentials" }); const token = issueToken(user); return res.json({ token, user: { id: user.id, username: user.username, team: user.team, role: user.role }, }); } catch (e) { console.error(e); return res.status(500).json({ error: "database_error" }); } }); // GET /api/auth/me router.get("/me", authMiddleware, async (req, res) => { try { const user = await getUserById(req.user.userId); if (!user) return res.status(404).json({ error: "user_not_found" }); const token = issueToken(user); return res.json({ token, user }); } catch (e) { console.error(e); return res.status(500).json({ error: "database_error" }); } }); export default router;