forked from hagopj13/node-express-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtoken.service.js
109 lines (101 loc) · 2.98 KB
/
token.service.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
const jwt = require('jsonwebtoken');
const moment = require('moment');
const httpStatus = require('http-status');
const config = require('../config/config');
const userService = require('./user.service');
const { Token } = require('../models');
const ApiError = require('../utils/ApiError');
const { tokenTypes } = require('../config/tokens');
/**
* Generate token
* @param {ObjectId} userId
* @param {Moment} expires
* @param {string} [secret]
* @returns {string}
*/
const generateToken = (userId, expires, type, secret = config.jwt.secret) => {
const payload = {
sub: userId,
iat: moment().unix(),
exp: expires.unix(),
type,
};
return jwt.sign(payload, secret);
};
/**
* Save a token
* @param {string} token
* @param {ObjectId} userId
* @param {Moment} expires
* @param {string} type
* @param {boolean} [blacklisted]
* @returns {Promise<Token>}
*/
const saveToken = async (token, userId, expires, type, blacklisted = false) => {
const tokenDoc = await Token.create({
token,
user: userId,
expires: expires.toDate(),
type,
blacklisted,
});
return tokenDoc;
};
/**
* Verify token and return token doc (or throw an error if it is not valid)
* @param {string} token
* @param {string} type
* @returns {Promise<Token>}
*/
const verifyToken = async (token, type) => {
const payload = jwt.verify(token, config.jwt.secret);
const tokenDoc = await Token.findOne({ token, type, user: payload.sub, blacklisted: false });
if (!tokenDoc) {
throw new Error('Token not found');
}
return tokenDoc;
};
/**
* Generate auth tokens
* @param {User} user
* @returns {Promise<Object>}
*/
const generateAuthTokens = async (user) => {
const accessTokenExpires = moment().add(config.jwt.accessExpirationMinutes, 'minutes');
const accessToken = generateToken(user.id, accessTokenExpires, tokenTypes.ACCESS);
const refreshTokenExpires = moment().add(config.jwt.refreshExpirationDays, 'days');
const refreshToken = generateToken(user.id, refreshTokenExpires, tokenTypes.REFRESH);
await saveToken(refreshToken, user.id, refreshTokenExpires, tokenTypes.REFRESH);
return {
access: {
token: accessToken,
expires: accessTokenExpires.toDate(),
},
refresh: {
token: refreshToken,
expires: refreshTokenExpires.toDate(),
},
};
};
/**
* Generate reset password token
* @param {string} email
* @returns {Promise<string>}
*/
const generateResetPasswordToken = async (email) => {
const user = await userService.getUserByEmail(email);
if (!user) {
throw new ApiError(httpStatus.NOT_FOUND, 'No users found with this email');
}
const expires = moment().add(config.jwt.resetPasswordExpirationMinutes, 'minutes');
const resetPasswordToken = generateToken(user.id, expires, tokenTypes.RESET_PASSWORD);
await saveToken(resetPasswordToken, user.id, expires, tokenTypes.RESET_PASSWORD);
return resetPasswordToken;
};
module.exports = {
generateToken,
saveToken,
verifyToken,
generateAuthTokens,
generateResetPasswordToken,
};