-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauth.ts
86 lines (72 loc) · 2.99 KB
/
auth.ts
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
84
85
86
import { HydratedDocument } from 'mongoose';
import { UserData, User } from '../db/schemas/User.model';
import { AuthtokenData, Authtoken } from '../db/schemas/Authtoken.model';
import { compareSync as comparePassword } from 'bcrypt';
import { v4 as uuidv4 } from 'uuid';
export interface AuthResult {
success: boolean;
user: HydratedDocument<UserData> | null;
authtoken: HydratedDocument<AuthtokenData> | null;
message?: string;
}
/**
* Authenticates a user based on a username and password
* @param username The user's username
* @param password The inputted password
* @returns An AuthResult type object containing success status and the user object if found
*/
export const authenticateUser = async (username: string, password: string): Promise<AuthResult> => {
// Get the user
const user: HydratedDocument<UserData> | null = await User.findOne({ username: username }).exec();
// If the user doesn't exist
if (!user) {
return { success: false, user: null, authtoken: null, message: `User doesn't exist.` };
}
// If the user is locked
if (user.locked) {
return { success: false, user: user, authtoken: null, message: `User locked.` };
}
const passwordMatches = comparePassword(password, user.password);
// If the password doesn't match
if (!passwordMatches) {
return { success: false, user: user, authtoken: null, message: `Incorrect password.` };
}
// Delete previous authentication tokens matching the user
await Authtoken.deleteMany({ user: user }).exec();
// The password matches, create an authentication token
const authtoken = await Authtoken.create({
user: user,
token: uuidv4(),
});
// Return the authentication data
return { success: true, user: user, authtoken: authtoken, message: `Successful authentication.` };
}
/**
* Validates an authentication token string
* @param token The authentication token string to validate
* @returns The authentication state of the user
*/
export const validateAuthenticationToken = async (token: string): Promise<AuthResult> => {
// Get the auth token
const authtoken: HydratedDocument<AuthtokenData> | null = await Authtoken.findOne({ token: token });
// If the auth token doesn't exist
if (!authtoken) {
return { success: false, user: null, authtoken: null, message: `Authtoken doesn't exist.` };
}
// If the auth token is expired
if (authtoken.expires < new Date()) {
return { success: false, user: null, authtoken: authtoken, message: `Authtoken is expired.` };
}
// Get the user
const user: HydratedDocument<UserData> | null = await User.findById(authtoken.user);
// If the user doesn't exist
if (!user) {
return { success: false, user: null, authtoken: authtoken, message: `User doesn't exist.` };
}
// If the user is locked
if (user.locked) {
return { success: false, user: user, authtoken: authtoken, message: `User locked.` };
}
// Return the authentication data
return { success: true, user: user, authtoken: authtoken, message: `Successful authentication.` };
}