· 6 years ago · Apr 13, 2020, 09:36 PM
1require("dotenv").config();
2import models from 'models'
3import pbkdf2 from 'pbkdf2';
4import jwt from 'jsonwebtoken'
5import {Settings} from 'auth/auth.settings'
6
7const apiUserGroup = 10;
8const {AuthenticationError} = require('apollo-server-express');
9const defaultError = 'Incorrect credentials';
10
11export default class Auth {
12 constructor(...params) {
13 [this.req, this.res] = params;
14 this._login(this.req)
15
16 }
17
18 async _login(req) {
19 const {username, password} = req.body;
20 const userFound = await models.User.findOne({
21 include: ['group'],
22 where: {username: username}
23 });
24
25 // User not found
26 if (!userFound || !userFound.is_active)
27 return this.emitError(defaultError);
28
29 // Check password
30 if (!password || !Auth._matchPass(password, userFound.password))
31 return this.emitError(defaultError);
32
33 // Check if user is API User
34 if (!Object.is(userFound.group.group_id, apiUserGroup))
35 return this.emitError(defaultError);
36
37 // All good.. Go and play!
38 this.emitSuccess(jwt.sign(
39 {
40 user_email: userFound.email,
41 user_id: userFound.id,
42 }, process.env.SECRET, {expiresIn: '1d'}
43 ), userFound)
44 }
45
46 static _matchPass(key, string) {
47 /***
48 * Check django pass
49 */
50 let parts = string.split('$');
51 let iterations = parts[1];
52 let salt = parts[2];
53
54 return pbkdf2.pbkdf2Sync(
55 key, salt, parseInt(iterations),
56 32, 'sha256'
57 ).toString('base64') === parts[3];
58 }
59
60 emitSuccess(token, user = null) {
61 let responseObject = {
62 success: true,
63 token: token,
64 };
65
66 // If user is staff response with
67 // extra credentials
68 if (user && user.is_staff)
69 responseObject = Object.assign(
70 {}, responseObject, Settings
71 );
72
73 // Response
74 this.res.send(
75 responseObject
76 )
77 }
78
79 emitError(error) {
80 this.res.status(403).send({
81 success: false,
82 message: error,
83 })
84
85 }
86
87 static context({req}) {
88 let jwt_resp = null;
89 let defaultError = 'Authentication token is invalid, please log in.';
90 let token = req.headers.authorization;
91 let headers = {headers: req.headers};
92
93 try {
94 // Valid response
95 jwt_resp = jwt.verify(
96 token.split(' ')[1], process.env.SECRET,
97 {maxAge: '2d'}
98 );
99 } catch (e) {
100 throw new AuthenticationError(defaultError)
101 }
102
103 // No exp in payload?
104 if (!jwt_resp || !('exp' in jwt_resp))
105 throw new AuthenticationError(defaultError);
106
107 return {headers, models, ...jwt_resp}
108
109
110 }
111}