-
Notifications
You must be signed in to change notification settings - Fork 1
/
auth.js
121 lines (89 loc) · 2.68 KB
/
auth.js
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
119
120
121
const express = require('express');
const passport = require('passport');
const { Strategy, ExtractJwt } = require('passport-jwt');
const jwt = require('jsonwebtoken');
const app = express();
app.use(express.json());
const users = require('./users');
const { validateUser } = require('./validation');
const {
JWT_SECRET: jwtSecret,
JWT_TOKEN_LIFETIME,
} = process.env;
if (!jwtSecret) {
console.error('JWT_SECRET not registered in .env');
process.exit(1);
}
let tokenLifetime = 60 * 60 * 24 * 31; // mánuður
if (JWT_TOKEN_LIFETIME) {
tokenLifetime = Number(JWT_TOKEN_LIFETIME);
}
const jwtOptions = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: jwtSecret,
};
async function strat(data, next) {
const user = await users.findById(data.id);
if (user) {
next(null, user);
} else {
next(null, false);
}
}
passport.use(new Strategy(jwtOptions, strat));
app.use(passport.initialize());
function requireAuth(req, res, next) {
return passport.authenticate(
'jwt',
{ session: false },
(err, user, info) => {
if (err) {
return next(err);
}
if (!user) {
const error = info && info.name === 'TokenExpiredError' ?
'expired token' : 'invalid token';
return res.status(401).json({ error });
}
req.user = user;
return next();
},
)(req, res, next);
}
async function registerRoute(req, res) {
const { username, password, name } = req.body;
const validationMessage = await validateUser({ username, password, name });
if (validationMessage.length > 0) {
return res.status(400).json({ errors: validationMessage });
}
const result = await users.createUser(username, password, name);
delete result.password;
return res.status(201).json(result);
}
async function loginRoute(req, res) {
const { username, password } = req.body;
const user = await users.findByUsername(username);
if (!user) {
return res.status(401).json({ error: 'No such user' });
}
const passwordIsCorrect = await users.comparePasswords(password, user.password);
if (passwordIsCorrect) {
const payload = { id: user.id };
const tokenOptions = { expiresIn: tokenLifetime };
const token = jwt.sign(payload, jwtOptions.secretOrKey, tokenOptions);
delete user.password;
return res.json({
user,
token,
expiresIn: tokenLifetime,
});
}
return res.status(401).json({ error: 'Invalid password!' });
}
function catchErrors(fn) {
return (req, res, next) => fn(req, res, next).catch(next);
}
app.post('/register', catchErrors(registerRoute));
app.post('/login', catchErrors(loginRoute));
module.exports = app;
module.exports.requireAuth = requireAuth;