|
| 1 | +/** using import statements in the electron / node files breaks npm start and nodepty |
| 2 | +* - types are left in place in these files for future iteration alternate import method is required for them to function |
| 3 | +*/ |
| 4 | + |
| 5 | +// import { expression } from "@babel/template"; |
| 6 | +// import { ErrorRequestHandler, NextFunction, Request, Response } from "express"; |
| 7 | +// import { Cursor } from "mongoose"; |
| 8 | +// import { BasicGroupByOptions } from "rxjs"; |
| 9 | +// import { userControllerType } from "../utils/backendTypes"; |
| 10 | + |
| 11 | +/** |
| 12 | + * Errors on lines 89-90 and 97-98 are due to Typescript not recognizing inherent _id property on MongoDB collections. |
| 13 | + */ |
| 14 | + |
| 15 | + |
1 | 16 | const { User } = require('../models/userModel');
|
2 | 17 | const bcrypt = require('bcryptjs');
|
3 | 18 |
|
4 |
| -const userController = {}; |
| 19 | +const userController/*: userControllerType*/ = { |
5 | 20 |
|
6 |
| -// Middleware to encrypt passwords using bcrypt |
7 |
| -userController.bcrypt = (req, res, next) => { |
8 |
| - // The cost factor determines how much time is needed to calculate a single bcrypt hash |
9 |
| - const saltRounds = 10; |
10 |
| - // Destructure password from request body |
11 |
| - const { password } = req.body; |
12 |
| - // Generate the salt by passing in saltRounds (cost factor) |
13 |
| - bcrypt.genSalt(saltRounds, (err, salt) => { |
14 |
| - // Hash a password by passing in the plaintext into the hash function |
15 |
| - bcrypt.hash(password, salt, (err, hash) => { |
16 |
| - // Save encrypted password into res.locals to be accessed later |
17 |
| - res.locals.encryptedPassword = hash; |
18 |
| - return next(); |
| 21 | + // Middleware to encrypt passwords using bcrypt |
| 22 | + bcrypt: (req/*: Request*/, res/*: Response*/, next/*: NextFunction*/)/*: void*/ => { |
| 23 | + // The cost factor determines how much time is needed to calculate a single bcrypt hash |
| 24 | + const saltRounds = 10; |
| 25 | + // Destructure password from request body |
| 26 | + const { password }/*: { password: String }*/ = req.body; |
| 27 | + // Generate the salt by passing in saltRounds (cost factor) |
| 28 | + bcrypt.genSalt(saltRounds, (err/*: ErrorRequestHandler*/, salt/*: String*/)/*: void*/ => { |
| 29 | + // Hash a password by passing in the plaintext into the hash function |
| 30 | + bcrypt.hash(password, salt, (err/*: ErrorRequestHandler*/, hash/*: String*/)/*: void*/ => { |
| 31 | + // Save encrypted password into res.locals to be accessed later |
| 32 | + res.locals.encryptedPassword = hash; |
| 33 | + return next(); |
| 34 | + }); |
19 | 35 | });
|
20 |
| - }); |
21 |
| -}; |
| 36 | + }, |
| 37 | + |
| 38 | + // Middleware to save user information in database |
| 39 | + signup: (req/*: Request*/, res/*: Response*/, next/*: NextFunction*/)/*: (void | Response)*/ => { |
| 40 | + // collection.create method to insert new user |
| 41 | + User.create( |
| 42 | + // Pass in username from request body and encrypted password |
| 43 | + { username/*: req.body.username*/, password/*: res.locals.encryptedPassword*/ }, |
| 44 | + // Callback to handle results of query |
| 45 | + (err/*: ErrorRequestHandler*/, newUser/*: (null | undefined | { _id: number })*/) => { |
| 46 | + if (!newUser) return res.status(400).json("Username already exists, please choose another one."); |
| 47 | + // If there is an error, invoke global error handler |
| 48 | + if (err) return next(err); |
| 49 | + // Save user ID into response locals |
| 50 | + res.locals.userId = newUser._id; |
| 51 | + // Inovke next middleware |
| 52 | + return next(); |
| 53 | + } |
| 54 | + ); |
| 55 | + }, |
22 | 56 |
|
23 |
| -// Middleware to save user information in database |
24 |
| -userController.signup = (req, res, next) => { |
25 |
| - // collection.create method to insert new user |
26 |
| - User.create( |
27 |
| - // Pass in username from request body and encrypted password |
28 |
| - { username: req.body.username, password: res.locals.encryptedPassword }, |
29 |
| - // Callback to handle results of query |
30 |
| - (err, newUser) => { |
31 |
| - if (!newUser) return res.status(400).json("Username already exists, please choose another one."); |
| 57 | + // Middleware to check credentials and log user into application |
| 58 | + login: (req/*: Request*/, res/*: Response*/, next/*: NextFunction*/)/*: void*/ => { |
| 59 | + // Collection.find method to look for all user instances with passed username |
| 60 | + User.find({ username/*: req.body.username*/ }, (err/*: ErrorRequestHandler*/, |
| 61 | + result/*: Array<{ _id: number, username: String, password: String }>*/)/*: void*/ => { |
32 | 62 | // If there is an error, invoke global error handler
|
33 | 63 | if (err) return next(err);
|
34 |
| - // Save user ID into response locals |
35 |
| - res.locals.userId = newUser._id; |
36 |
| - // Inovke next middleware |
37 |
| - return next(); |
38 |
| - } |
39 |
| - ); |
40 |
| -}; |
| 64 | + // If there are no matching usernames, invoke global error handler |
| 65 | + if (result.length === 0) return next('Incorrect username/password combo'); |
| 66 | + // If there is a user with passed username, use the bcrypt.compare method to compare plaintext password with encrypted password |
| 67 | + bcrypt.compare(req.body.password, result[0].password, (err/*: ErrorRequestHandler*/, match/*: boolean*/) => { |
| 68 | + // If an error occurs in the compare method, invoke global error handler |
| 69 | + if (err) return next(err); |
| 70 | + // If there is a match, invoke next middleware |
| 71 | + if (match) { |
| 72 | + res.locals.userId = result[0]._id; |
| 73 | + return next(); |
| 74 | + } |
| 75 | + // If there is no match, invoke global error handler |
| 76 | + return next('Incorrect username/password combination'); |
| 77 | + }); |
| 78 | + }); |
| 79 | + }, |
41 | 80 |
|
42 |
| -// Middleware to check credentials and log user into application |
43 |
| -userController.login = (req, res, next) => { |
44 |
| - // Collection.find method to look for all user instances with passed username |
45 |
| - User.find({ username: req.body.username }, (err, result) => { |
46 |
| - // If there is an error, invoke global error handler |
47 |
| - if (err) return next(err); |
48 |
| - // If there are no matching usernames, invoke global error handler |
49 |
| - if (result.length === 0) return next('Incorrect username/password combo'); |
50 |
| - // If there is a user with passed username, use the bcrypt.compare method to compare plaintext password with encrypted password |
51 |
| - bcrypt.compare(req.body.password, result[0].password, (err, match) => { |
52 |
| - // If an error occurs in the compare method, invoke global error handler |
| 81 | + getUsers: (req/*: Request*/, res/*: Response*/, next/*: NextFunction*/)/*: void*/ => { |
| 82 | + // Collection.find method to look for all user instances with passed username |
| 83 | + User.find({}, (err/*: ErrorRequestHandler*/, result/*: Array<{ _id: number, username: String, password: String }>*/) => { |
| 84 | + // If there is an error, invoke global error handler |
53 | 85 | if (err) return next(err);
|
54 |
| - // If there is a match, invoke next middleware |
55 |
| - if (match) { |
56 |
| - res.locals.userId = result[0]._id; |
57 |
| - return next(); |
58 |
| - } |
59 |
| - // If there is no match, invoke global error handler |
60 |
| - return next('Incorrect username/password combination'); |
| 86 | + res.locals.users = result; |
| 87 | + return next(); |
61 | 88 | });
|
62 |
| - }); |
63 |
| -}; |
| 89 | + }, |
64 | 90 |
|
65 |
| -userController.getUsers = (req, res, next) => { |
66 |
| - // Collection.find method to look for all user instances with passed username |
67 |
| - User.find({}, (err, result) => { |
68 |
| - // If there is an error, invoke global error handler |
69 |
| - if (err) return next(err); |
70 |
| - res.locals.users = result; |
71 |
| - return next(); |
72 |
| - }); |
73 |
| -}; |
74 |
| - |
75 |
| -userController.githubLogin = (req, res, next) => { |
76 |
| - // store user._id in res.locals |
77 |
| - res.locals.userId = req.user._id; |
| 91 | + githubLogin: (req/*: Request*/, res/*: Response*/, next/*: NextFunction*/)/*: void*/ => { |
| 92 | + // store user._id in res.locals |
| 93 | + if(!req.user || !req.user._id) throw new Error("User or user ID not defined.") |
| 94 | + res.locals.userId = req.user._id; |
78 | 95 |
|
79 |
| - return next(); |
80 |
| -}; |
| 96 | + return next(); |
| 97 | + }, |
81 | 98 |
|
82 |
| -userController.googleLogin = (req, res, next) => { |
83 |
| - // store user._id in res.locals |
84 |
| - res.locals.userId = req.user._id; |
| 99 | + googleLogin: (req/*: Request*/, res/*: Response*/, next/*: NextFunction*/)/*: void*/ => { |
| 100 | + // store user._id in res.locals |
| 101 | + if(!req.user || !req.user._id) throw new Error("User or user ID not defined.") |
| 102 | + res.locals.userId = req.user._id; |
85 | 103 |
|
86 |
| - return next(); |
| 104 | + return next(); |
| 105 | + } |
87 | 106 | };
|
88 | 107 |
|
89 | 108 | module.exports = userController;
|
0 commit comments