Snapshot: full project state
This commit is contained in:
83
pettalk-auth-routes.ts
Normal file
83
pettalk-auth-routes.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { Router, Request, Response } from "express";
|
||||
import jwt from "jsonwebtoken";
|
||||
import { createUser, authenticateUser, getUserById, UserPublic } from "./database.js";
|
||||
|
||||
const JWT_SECRET = process.env.JWT_SECRET || "pettalk-dev-secret-change-in-production";
|
||||
const TOKEN_EXPIRY = "7d";
|
||||
|
||||
const router = Router();
|
||||
|
||||
function generateToken(user: UserPublic): string {
|
||||
return jwt.sign({ userId: user.id, email: user.email }, JWT_SECRET, {
|
||||
expiresIn: TOKEN_EXPIRY,
|
||||
});
|
||||
}
|
||||
|
||||
// POST /api/register
|
||||
router.post("/register", (req: Request, res: Response) => {
|
||||
try {
|
||||
const { username, email, password } = req.body;
|
||||
|
||||
if (!username || !email || !password) {
|
||||
return res.status(400).json({ error: "Username, email, and password are required." });
|
||||
}
|
||||
|
||||
if (password.length < 6) {
|
||||
return res.status(400).json({ error: "Password must be at least 6 characters." });
|
||||
}
|
||||
|
||||
const user = createUser(username, email, password);
|
||||
const token = generateToken(user);
|
||||
|
||||
return res.status(201).json({ user, token });
|
||||
} catch (err: any) {
|
||||
if (err.message?.includes("already exists")) {
|
||||
return res.status(409).json({ error: err.message });
|
||||
}
|
||||
console.error("Register error:", err);
|
||||
return res.status(500).json({ error: "Registration failed." });
|
||||
}
|
||||
});
|
||||
|
||||
// POST /api/login
|
||||
router.post("/login", (req: Request, res: Response) => {
|
||||
try {
|
||||
const { email, password } = req.body;
|
||||
|
||||
if (!email || !password) {
|
||||
return res.status(400).json({ error: "Email and password are required." });
|
||||
}
|
||||
|
||||
const user = authenticateUser(email, password);
|
||||
const token = generateToken(user);
|
||||
|
||||
return res.json({ user, token });
|
||||
} catch (err: any) {
|
||||
if (err.message?.includes("Invalid")) {
|
||||
return res.status(401).json({ error: err.message });
|
||||
}
|
||||
console.error("Login error:", err);
|
||||
return res.status(500).json({ error: "Login failed." });
|
||||
}
|
||||
});
|
||||
|
||||
// GET /api/me — protected by authMiddleware
|
||||
router.get("/me", (req: Request, res: Response) => {
|
||||
try {
|
||||
const userId = (req as any).userId;
|
||||
if (!userId) {
|
||||
return res.status(401).json({ error: "Authentication required." });
|
||||
}
|
||||
|
||||
const user = getUserById(userId);
|
||||
if (!user) {
|
||||
return res.status(404).json({ error: "User not found." });
|
||||
}
|
||||
|
||||
return res.json({ user });
|
||||
} catch (err: any) {
|
||||
return res.status(500).json({ error: "Failed to fetch user." });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user