Passed
Pull Request — main (#12)
by Julia
01:58
created

server/src/models/emp.js   A

Complexity

Total Complexity 10
Complexity/F 1.67

Size

Lines of Code 132
Function Count 6

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 10
eloc 60
mnd 4
bc 4
fnc 6
dl 0
loc 132
rs 10
bpm 0.6666
cpm 1.6666
noi 0
c 0
b 0
f 0

2 Functions

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