1.9 KB75 lines
Blame
1const jwt = require("jsonwebtoken");
2const cookie = require("cookie");
3
4const JWT_SECRET = process.env.JWT_SECRET || "grove-dev-secret";
5
6function verifyToken(token) {
7 return jwt.verify(token, JWT_SECRET);
8}
9
10function extractToken(req) {
11 // 1. Authorization header
12 const authHeader = req.headers?.authorization;
13 if (authHeader && authHeader.startsWith("Bearer ")) {
14 return authHeader.slice(7);
15 }
16 // 2. Cookie
17 const cookieHeader = req.headers?.cookie;
18 if (cookieHeader) {
19 const cookies = cookie.parse(cookieHeader);
20 if (cookies.grove_hub_token) return cookies.grove_hub_token;
21 }
22 return null;
23}
24
25// Express middleware
26function requireAuth(req, res, next) {
27 const token = extractToken(req);
28 if (!token) return res.status(401).json({ error: "Unauthorized" });
29 try {
30 req.user = verifyToken(token);
31 req.token = token;
32 next();
33 } catch {
34 return res.status(401).json({ error: "Unauthorized" });
35 }
36}
37
38// Socket.IO middleware for /collab namespace
39function socketAuth(socket, next) {
40 // 1. Handshake auth (client passes { auth: { token } })
41 let token = socket.handshake.auth?.token;
42 // 2. Fallback to cookie
43 if (!token) {
44 const cookieHeader = socket.handshake.headers?.cookie;
45 if (cookieHeader) {
46 const cookies = cookie.parse(cookieHeader);
47 token = cookies.grove_hub_token;
48 }
49 }
50 if (!token) return next(new Error("unauthorized"));
51 try {
52 socket.user = verifyToken(token);
53 socket.token = token;
54 next();
55 } catch {
56 return next(new Error("unauthorized"));
57 }
58}
59
60// Like requireAuth but does not reject — just attaches user/token if present.
61function optionalAuth(req, res, next) {
62 const token = extractToken(req);
63 if (token) {
64 try {
65 req.user = verifyToken(token);
66 req.token = token;
67 } catch {
68 // invalid token — treat as unauthenticated
69 }
70 }
71 next();
72}
73
74module.exports = { verifyToken, extractToken, requireAuth, optionalAuth, socketAuth };
75