-
-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathpassport.config.ts
More file actions
85 lines (67 loc) · 2.19 KB
/
passport.config.ts
File metadata and controls
85 lines (67 loc) · 2.19 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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import axios from 'axios'
import { NextFunction, Request, Response } from 'express'
import passport from 'passport'
import { ExtractJwt, Strategy } from 'passport-jwt'
import User from '../models/user'
import { handleError, UserBanned, UserNoAuth } from '../utils/errors.utils'
passport.serializeUser((user, done) => done(null, user))
passport.deserializeUser((id, done) => done(null, id))
passport.use(new Strategy({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.JWT_KEY
}, async ({ id }, done) => {
const noSessionResponses = ['USER_NO_AUTH', 'USER_NOT_FOUND']
try {
const user = await new User().load(id)
return done(null, user)
} catch (error) {
if (error.response.indexOf(noSessionResponses))
return done(UserNoAuth)
done(error)
}
}))
const BAN_SAFE_ENDPOINTS = [
'GET /user/me'
]
const fetchEndpoint = (req: Request) => `${req.method} ${req.baseUrl}${req.route.path}`
const fetchUser = async (
req: Request,
res: Response,
next: NextFunction
) => new Promise<User>(async (resolve, reject) => {
try {
if (process.env.AUTH_BASE_URL) {
const { authorization } = req.headers
const token = authorization.split(' ')[1]
const { data: { resource } } = await axios.post(process.env.AUTH_BASE_URL, { token })
const user = new User(resource)
resolve(user)
} else {
passport.authenticate('jwt', { session: false }, async (err, user: User) => {
if (err)
return handleError(err, res)
if (!user)
return handleError(UserNoAuth, res)
resolve(user)
})(req, res, next)
}
} catch (error) {
reject(error)
}
})
export const authenticate = async (req: Request, res: Response, next: NextFunction) => {
try {
const user = await fetchUser(req, res, next)
const endpoint = fetchEndpoint(req)
const ban = await user.fetchBan()
if (ban && BAN_SAFE_ENDPOINTS.includes(endpoint))
return handleError(UserBanned, res)
if (req.baseUrl === '/admin' && !user.roles.includes('admin'))
return handleError(UserNoAuth, res)
req.user = user
next()
} catch (error) {
handleError(error, res)
}
}
export default passport