-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathauthMiddleware.js
More file actions
64 lines (52 loc) · 1.39 KB
/
authMiddleware.js
File metadata and controls
64 lines (52 loc) · 1.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
const jwt = require('jsonwebtoken');
const { UnauthorizedError, ForbiddenError } = require('./errors');
const verifyToken = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return next(new UnauthorizedError('No token provided'));
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (err) {
if (err.name === 'TokenExpiredError') {
return next(new UnauthorizedError('Token expired'));
}
next(new UnauthorizedError('Invalid token'));
}
};
const requireRole = (roles) => {
return (req, res, next) => {
if (!req.user) {
return next(new UnauthorizedError('User not authenticated'));
}
if (!roles.includes(req.user.role)) {
return next(new ForbiddenError(`Required role: ${roles.join(', ')}`));
}
next();
};
};
const rateLimitByUser = (store) => {
return (req, res, next) => {
const key = `${req.user?.id || req.ip}`;
const limit = 100;
const window = 3600;
store.increment(key, (err, count) => {
if (err) return next(err);
if (count === 1) {
store.expire(key, window);
}
if (count > limit) {
res.set('Retry-After', window);
return next(new Error('Rate limit exceeded'));
}
next();
});
};
};
module.exports = {
verifyToken,
requireRole,
rateLimitByUser,
};