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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 326 by rakin, Mon Jul 29 17:29:33 2024 UTC revision 349 by rakin, Mon Jul 29 17:29:43 2024 UTC
# Line 1  Line 1 
1  import { Request } from "express";  import { Request } from "express";
2    import User from "../../models/User";
3  import Controller from "../Controller";  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 {  export default class UserController extends Controller {
13      public async index(request: Request) {      middleware(): KeyValuePair<Function[]> {
14          return { message: "Server is up." };          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  }  }

Legend:
Removed from v.326  
changed lines
  Added in v.349

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26