Snapshot: full project state
This commit is contained in:
42
pettalk-auth-middleware.ts
Normal file
42
pettalk-auth-middleware.ts
Normal 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." });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user