/[sudobot]/trunk/src/api/controllers/UserController.ts
ViewVC logotype

Contents of /trunk/src/api/controllers/UserController.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 349 - (show annotations)
Mon Jul 29 17:29:43 2024 UTC (8 months, 1 week ago) by rakin
File MIME type: application/typescript
File size: 4663 byte(s)
feat(api): auth middleware
1 import { Request } from "express";
2 import User from "../../models/User";
3 import Controller from "../Controller";
4 import { body } from 'express-validator';
5 import bcrypt from 'bcrypt';
6 import jwt from 'jsonwebtoken';
7 import KeyValuePair from "../../types/KeyValuePair";
8 import Response from "../Response";
9 import ValidatorError from "../middleware/ValidatorError";
10 import RequireAuth from "../middleware/RequireAuth";
11
12 export default class UserController extends Controller {
13 middleware(): KeyValuePair<Function[]> {
14 return {
15 create: [
16 body(["password"]).isLength({ min: 2 }),
17 body(["username"]).custom(async username => {
18 const user = await User.findOne({ username });
19
20 if (user) {
21 return Promise.reject("Username is already in use");
22 }
23
24 return username;
25 }),
26 body(["discord_id"]).custom(value => /\d+/g.test(value) ? value : Promise.reject("Invalid Snowflake Given"))
27 ],
28 login: [
29 body(["username", "password"]).isLength({ min: 2 }),
30 ],
31 delete: [
32 RequireAuth,
33 body(["username", "password"]).isLength({ min: 2 }),
34 ]
35 };
36 }
37
38 globalMiddleware(): Function[] {
39 return [ValidatorError];
40 }
41
42 public async index() {
43 return new Response(403);
44 return await User.find().select(["_id", "username", "createdAt"]).limit(30);
45 }
46
47 public async create(request: Request) {
48 return new Response(403);
49
50 const user = new User();
51
52 user.username = request.body.username;
53 user.discord_id = request.body.discord_id;
54 user.createdAt = new Date();
55 user.tokenUpdatedAt = new Date();
56
57 try {
58 await user.save();
59 }
60 catch (e) {
61 return { error: "DB validation error", error_type: 'db_validation' };
62 }
63
64 const salt = await bcrypt.genSalt();
65 user.password = await bcrypt.hash(request.body.password, salt);
66
67 const token = await jwt.sign({
68 username: user.username,
69 discord_id: user.discord_id,
70 _id: user.id
71 }, process.env.JWT_SECRET!, {
72 expiresIn: "2 days",
73 issuer: "SudoBot API",
74 });
75
76 user.token = token;
77
78 try {
79 await user.save();
80 }
81 catch (e) {
82 return { error: "Token signing error", error_type: 'token_signing' };
83 }
84
85 user.password = undefined;
86 return user;
87 }
88
89 public async delete(request: Request) {
90 const { username, password } = request.body;
91 const user = await User.findOne({ username });
92
93 if (!user) {
94 return { error: "Username is incorrect." };
95 }
96
97 if (!(await bcrypt.compare(password, user.password!))) {
98 return { error: "Password is incorrect." };
99 }
100
101 await user.delete();
102
103 user.password = undefined;
104 user.token = undefined;
105 user.tokenUpdatedAt = undefined;
106
107 return {
108 message: "Account deletion successful",
109 user
110 };
111 }
112
113 public async login(request: Request) {
114 const { username, password } = request.body;
115 const user = await User.findOne({ username });
116
117 if (!user) {
118 return { error: "Username is incorrect." };
119 }
120
121 if (!(await bcrypt.compare(password, user.password!))) {
122 return { error: "Password is incorrect." };
123 }
124
125 let { token } = user;
126
127 try {
128 if (!token) {
129 throw new Error("Token is not set");
130 }
131
132 if (!jwt.verify(token, process.env.JWT_SECRET!)) {
133 throw new Error("Token is not valid");
134 }
135 }
136 catch (e) {
137 console.log(e);
138
139 const newToken = await jwt.sign({
140 username: user.username,
141 discord_id: user.discord_id,
142 _id: user.id
143 }, process.env.JWT_SECRET!, {
144 expiresIn: "2 days",
145 issuer: "SudoBot API",
146 });
147
148 token = newToken;
149 user.tokenUpdatedAt = new Date();
150 user.token = newToken;
151 await user.save();
152 }
153
154 return {
155 message: "Login successful",
156 username,
157 token,
158 expires: new Date(user.tokenUpdatedAt!.getTime() + (2 * 24 * 60 * 60 * 1000))
159 };
160 }
161 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26