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
|
/**
* Authentication helper functions.
* @module app/services/authentication/helpers
*/
import jsonwebtoken from "jsonwebtoken";
import expressJwt from "express-jwt";
import { createHmac, createHash, randomBytes } from "crypto";
/**
* Generate a random secret
* @return {string} a random 64-byte secret token
*/
export const generateSecret = () => randomBytes(64).toString("hex");
/**
* Store a password as SHA256 using the secret token
* @param {string} plainPassword the plaintext password
* @return {string} the sha256 of the password
*/
export const encryptPassword = (plainPassword) =>
createHmac("sha256", process.env.TOKEN_SECRET)
.update(plainPassword, "utf8")
.digest("hex");
/**
* Generate a JSON web token with the desired payload.
* @param {Object} payload the object to attach to the JWT
* @return {string} a JSON web token
*/
export const generateAccessToken = (payload) =>
jsonwebtoken.sign(payload, process.env.TOKEN_SECRET);
/**
* Middleware to encrypt any passwords before they hit the database.
*/
export const storeEncryptedPassword = (request, response, next) => {
if (request.body.password) {
request.body.password = encryptPassword(request.body.password);
}
next();
};
/**
* Hash a password, used in testing and when seeding the databse.
* Typically the passwords are hashed on the client side before being transmitted,
* and then hashed again before being inserted into the database.
* @param {string} plaintext the plaintext password
* @return {string} the SHA256 of the password
*/
export function hashPassword(plaintext) {
return createHash("sha256").update(plaintext, "utf8").digest("base64");
}
/**
* Express JWT middleware.
* @param {object} options options to pass to express-jwt
* @return {Function} the express-jwt middleware
*/
export function checkAccessToken(options = {}) {
if (!process.env.TOKEN_SECRET) return null;
return expressJwt({
secret: process.env.TOKEN_SECRET,
algorithms: ["HS256"],
credentialsRequired: true,
...options,
});
}
/**
* Middleware to check if a user is active before performing an API call.
*/
export async function checkUserIsActive(request, response, next) {
const User = request.bookshelf.model("User");
const user = await new User({
user_id: request.user.user_id,
}).fetch();
if (!user.get("is_active")) {
next(new Error("UserNotActive"));
} else {
next();
}
}
|