Passed
Pull Request — main (#12)
by Julia
02:06
created

server/src/models/emp.js   A

Complexity

Total Complexity 11
Complexity/F 1.57

Size

Lines of Code 142
Function Count 7

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 11
eloc 62
mnd 4
bc 4
fnc 7
dl 0
loc 142
rs 10
bpm 0.5714
cpm 1.5713
noi 0
c 0
b 0
f 0

2 Functions

Rating   Name   Duplication   Size   Complexity  
B emp.js ➔ login 0 12 7
A emp.js ➔ comparePasswords 0 40 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
            // om inget token är med kommer det att kastas
44
            // ett fel här eftersom decoded inte kommer ha attributet role som alla token
45
            // som tillhör anställda ska ha
46
            if (!acceptableRoles.includes(decoded.role)) {
47
                // if unauthorized request it is safer
48
                // to make it look like the page does not
49
                // exist
50
                return res.status(404).json({
51
                    errors: {
52
                        status: 404,
53
                        source: req.originalUrl,
54
                        title: "Not found",
55
                        detail: "Page not found"
56
                    }
57
                });
58
            }
59
60
            // kallar den för emp för att skilja från user attributet som kan vara med i vissa förfrågningar
61
            req.body.emp = {
62
                id: decoded.id,
63
                role: decoded.role
64
            };
65
66
            return next();
67
        });
68
    },
69
70
    /**
71
     * @description Function that handles admin login
72
     *
73
     * @param {Request} req Request object
74
     * @param {Response} res Response object
75
     * @param {Function} next Next function
76
     *
77
     * @returns {Object} JSON object
78
     */
79
    login: async function login(req, res) {
80
        const username = req.body.username;
81
        const password = req.body.password;
82
83
        const emp = await this.getOneFromDB(username);
84
85
        // om användarnamn saknas kommer
86
        // databasen lyfta ett error
87
        // om lösenord saknas kommer det fångas i bcrypt compare
88
89
        return this.comparePasswords(res, password, emp);
90
    },
91
    /**
92
     * @description Function that compares passwords
93
     *
94
     * @param {Request} req Request object
95
     * @param {String} password Password
96
     * @param {Object} user User
97
     *
98
     * @returns {Object} JSON object
99
     */
100
    comparePasswords: function comparePasswords(res, password, emp) {
101
        bcrypt.compare(password, emp.hash, (err, result) => {
102
            if (err) {
103
                return res.status(500).json({
104
                    errors: {
105
                        status: 500,
106
                        source: "/login",
107
                        title: "bcrypt error",
108
                        detail: "bcrypt error"
109
                    }
110
                });
111
            }
112
113
            if (result) {
114
                const payload = {
115
                    id: emp.id,
116
                    role: emp.role 
117
                };
118
                const jwtToken = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: "24h" });
119
120
                return res.json({
121
                    data: {
122
                        type: "success",
123
                        message: "User logged in",
124
                        user: payload,
125
                        token: jwtToken
126
                    }
127
                });
128
            }
129
130
            return res.status(401).json({
131
                errors: {
132
                    status: 401,
133
                    source: "/login",
134
                    title: "Wrong password",
135
                    detail: "Password is incorrect."
136
                }
137
            });
138
        });
139
    }
140
};
141
142
export default emp;