unoffical wafrn mirror
wafrn.net
atproto
social-network
activitypub
1import { Request, Response, NextFunction } from 'express'
2import jwt from 'jsonwebtoken'
3import { completeEnvironment } from './backendOptions.js'
4import AuthorizedRequest from '../interfaces/authorizedRequest.js'
5import { User } from '../models/index.js'
6import { Op } from 'sequelize'
7import { redisCache } from './redis.js'
8import { logger } from './logger.js'
9
10function authenticateToken(req: Request, res: Response, next: NextFunction) {
11 const authHeader = req.headers.authorization
12 const token = authHeader?.split(' ')[1]
13
14 if (token == null) return res.sendStatus(401)
15 // TODO make this code "a bit better" and less duplicate. Not big deal because this code should not be touched.... but you know
16 jwt.verify(token, completeEnvironment.jwtSecret, async (err: any, jwtData: any) => {
17 if (err) {
18 logger.debug({
19 message: `Error on token`,
20 err
21 })
22 return res.sendStatus(401)
23 }
24 if (!jwtData?.userId) {
25 logger.debug({
26 message: `No token on id`
27 })
28 return res.sendStatus(401)
29 }
30 const userCacheHit = await redisCache.get('auth:' + jwtData.userId)
31 if (userCacheHit) {
32 ;(req as AuthorizedRequest).jwtData = jwtData
33 next()
34 } else {
35 const user = await User.findOne({
36 attributes: ['id', 'banned', 'activated'],
37 where: {
38 id: jwtData.userId,
39 banned: { [Op.ne]: true },
40 activated: true
41 }
42 })
43 if (user) {
44 // a ban can take up to 5 minutes on some view only routes
45 await redisCache.set('auth:' + jwtData.userId, 't', 'EX', 30)
46 ;(req as AuthorizedRequest).jwtData = jwtData
47 next()
48 } else {
49 logger.debug({
50 message: `User not found: ${jwtData.userId}`,
51 err
52 })
53 return res.sendStatus(401)
54 }
55 }
56 })
57}
58
59function adminToken(req: AuthorizedRequest, res: Response, next: NextFunction) {
60 if (req.jwtData?.role === 10) {
61 next()
62 } else {
63 return res.sendStatus(401)
64 }
65}
66
67export { authenticateToken, adminToken }