Passed
Push — main ( 55cb12...5d5954 )
by Martin
01:05 queued 16s
created

emp.js ➔ comparePasswords   A

Complexity

Conditions 4

Size

Total Lines 40
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 26
dl 0
loc 40
rs 9.256
c 0
b 0
f 0
cc 4
1
import bcrypt from "bcryptjs";
2
import jwt from "jsonwebtoken";
3
import { db } from "./db.js"
4
5
6
// separata modeller för emp och user eftersom
7
// inloggningen och registereringen fungerar annorlunda
8
// och checkToken funktionen kommer också skilja sig,
9
// dels ingen check för roll och dets lyfta ut idt och lägga till på req.body
10
const emp = {
11
    getOneFromDb: async function(username) {
12
        const result = await db.queryWithArgs(`CALL emp_login(?);`, [username]);
13
        return result[0][0];
14
    },
15
    checkAdminAcc: function(req, res, next) {
16
        this.checkToken(req, res, next, ["admin"]);
17
    },
18
    /**
19
     * 
20
     * @param {*} req 
21
     * @param {*} res 
22
     * @param {*} next 
23
     * @param {Array} acceptableRoles array with acceptable roles, for example ["admin"] or ["admin", "superadmin"]
24
     */
25
    checkToken: function(req, res, next, acceptableRoles) {
26
        let token = req.headers["x-access-token"];
27
28
        jwt.verify(token, process.env.JWT_SECRET, function (err, decoded) {
29
            // if no token has been provided,
30
            // or if provided token is expired
31
            // this block will be executed
32
            if (err) {
33
                return res.status(500).json({
34
                    errors: {
35
                        status: 500,
36
                        source: "authorization",
37
                        title: "Failed authentication",
38
                        detail: err.message
39
                    }
40
                });
41
            }
42
43
            if (!acceptableRoles.includes(decoded.role)) {
44
                // if unauthorized request it is safer
45
                // to make it look like the page does not
46
                // exist
47
                return res.status(404).json({
48
                    errors: {
49
                        status: 404,
50
                        source: req.originalUrl,
51
                        title: "Not found",
52
                        detail: "Page not found"
53
                    }
54
                });
55
            }
56
57
            // kallar den för emp för att skilja från user attributet som kan vara med i vissa förfrågningar
58
            req.body.emp = {
59
                id: decoded.id,
60
                role: decoded.role
61
            };
62
63
            return next();
64
        });
65
    },
66
67
    /**
68
     * @description Function that handles admin login
69
     *
70
     * @param {Request} req Request object
71
     * @param {Response} res Response object
72
     * @param {Function} next Next function
73
     *
74
     * @returns {Object} JSON object
75
     */
76
    login: async function login(req, res) {
77
        const username = req.body.username;
78
        const password = req.body.password;
79
80
        const emp = await this.getOneFromDB(username);
81
82
        // om användarnamn saknas kommer
83
        // databasen lyfta ett error
84
        // om lösenord saknas kommer det fångas i bcrypt compare
85
86
        return this.comparePasswords(res, password, emp);
87
    },
88
    /**
89
     * @description Function that compares passwords
90
     *
91
     * @param {Request} req Request object
92
     * @param {String} password Password
93
     * @param {Object} user User
94
     *
95
     * @returns {Object} JSON object
96
     */
97
    comparePasswords: function comparePasswords(res, password, emp) {
98
        bcrypt.compare(password, emp.hash, (err, result) => {
99
            if (err) {
100
                return res.status(500).json({
101
                    errors: {
102
                        status: 500,
103
                        source: "/login",
104
                        title: "bcrypt error",
105
                        detail: "bcrypt error"
106
                    }
107
                });
108
            }
109
110
            if (result) {
111
                const payload = {
112
                    id: emp.id,
113
                    role: emp.role 
114
                };
115
                const jwtToken = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: "24h" });
116
117
                return res.json({
118
                    data: {
119
                        type: "success",
120
                        message: "User logged in",
121
                        user: payload,
122
                        token: jwtToken
123
                    }
124
                });
125
            }
126
127
            return res.status(401).json({
128
                errors: {
129
                    status: 401,
130
                    source: "/login",
131
                    title: "Wrong password",
132
                    detail: "Password is incorrect."
133
                }
134
            });
135
        });
136
    }
137
};
138
139
export default emp;