Snapshot: full project state

This commit is contained in:
2026-10-06 23:43:43 -07:00
commit fc6d00988c
13 changed files with 1283 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
import { Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";
const JWT_SECRET = process.env.JWT_SECRET || "pettalk-dev-secret-change-in-production";
// Public routes that don't require authentication
const PUBLIC_ROUTES = [
{ method: "POST", path: "/api/register" },
{ method: "POST", path: "/api/login" },
{ method: "GET", path: "/api/health" },
];
export function authMiddleware(req: Request, res: Response, next: NextFunction) {
// Skip auth for public routes
const isPublic = PUBLIC_ROUTES.some(
(r) => r.method === req.method && req.path === r.path
);
if (isPublic) {
return next();
}
// Also skip non-API routes (static files, SPA routes)
if (!req.path.startsWith("/api/")) {
return next();
}
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith("Bearer ")) {
return res.status(401).json({ error: "Authentication required." });
}
const token = authHeader.split(" ")[1];
try {
const decoded = jwt.verify(token, JWT_SECRET) as { userId: number; email: string };
(req as any).userId = decoded.userId;
(req as any).userEmail = decoded.email;
next();
} catch (err) {
return res.status(401).json({ error: "Invalid or expired token." });
}
}