-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Expand file tree
/
Copy pathauth-middleware.js
More file actions
118 lines (104 loc) · 2.77 KB
/
auth-middleware.js
File metadata and controls
118 lines (104 loc) · 2.77 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
const { JWT_SECRET } = require("../secrets"); // use this secret!
const usersModel = require('../users/users-model')
const restricted = (req, res, next) => {
/*
If the user does not provide a token in the Authorization header:
status 401
{
"message": "Token required"
}
If the provided token does not verify:
status 401
{
"message": "Token invalid"
}
Put the decoded token in the req object, to make life easier for middlewares downstream!
*/
const token = req.headers.authorization
if(!token){
res.status(401).json({
message:"Token required"
})
} else {
jwt.verify(token,JWT_SECRET,(err,decoded)=>{
if(err){
res.status(401).json("Token invalid" )
}else{
req.decodedToken = decoded
next()
}
})
}
}
const only = role_name => (req, res, next) => {
/*
If the user does not provide a token in the Authorization header with a role_name
inside its payload matching the role_name passed to this function as its argument:
status 403
{
"message": "This is not for you"
}
Pull the decoded token from the req object, to avoid verifying it again!
*/
if (!req.decodedToken.role_name === role_name){
res.status(403).json({
message: "This is not for you"
})
}else{
next()
}
}
const checkUsernameExists = async (req, res, next) => {
/*
If the username in req.body does NOT exist in the database
status 401
{
"message": "Invalid credentials"
}
*/
try{
const [user] = await usersModel.findBy({username: req.body.username})
if(!user){
next({ status: 422, message:"Invalid credentials" })
}else{
req.user = user
next()
}
}catch(err){
next(err)
}
}
const validateRoleName = (req, res, next) => {
/*
If the role_name in the body is valid, set req.role_name to be the trimmed string and proceed.
If role_name is missing from req.body, or if after trimming it is just an empty string,
set req.role_name to be 'student' and allow the request to proceed.
If role_name is 'admin' after trimming the string:
status 422
{
"message": "Role name can not be admin"
}
If role_name is over 32 characters after trimming the string:
status 422
{
"message": "Role name can not be longer than 32 chars"
}
*/
if(!req.body.role_name || !req.body.role_name.trim()){
req.role_name = 'student'
next()
} else if(req.body.role_name.trim() === 'admin') {
next({ status: 422, message: "Role name can not be admin" })
}else if(req.body.role_name.trim().length > 32 ) {
next({ status: 422, message: "Role name can not be longer than 32 chars" })
}else{
req.role_name = req.body.role_name.trim()
next()
}
}
module.exports = {
restricted,
checkUsernameExists,
validateRoleName,
only,
}