diff --git a/api/main_endpoints/routes/Auth.js b/api/main_endpoints/routes/Auth.js index 74c55053a..f92555b97 100644 --- a/api/main_endpoints/routes/Auth.js +++ b/api/main_endpoints/routes/Auth.js @@ -135,100 +135,70 @@ router.post('/sendPasswordReset', async (req, res) => { }); // User Login -router.post('/login', function(req, res) { - if (!req.body.email || !req.body.password) { - return res.sendStatus(BAD_REQUEST); - } +router.post('/login', async (req, res) => { + try { + const { email, password } = req.body; + if (!email || !password) return res.sendStatus(BAD_REQUEST); - User.findOne( - { - email: req.body.email.toLowerCase() - }, - function(error, user) { - if (error) { - logger.error('/login User.findOne had an error', error); - return res.status(BAD_REQUEST).send({ message: 'Bad Request.' }); - } + const user = await User.findOne({ email: email.toLowerCase() }); + const isMatch = await new Promise((resolve, reject) => { if (!user) { - return res - .status(UNAUTHORIZED) - .send({ - message: 'Username or password does not match our records.' - }); + resolve(false); } + user.comparePassword(req.body.password, (err, match) => { + if (err) reject(err); + resolve(match); + }); + }); - // Check if password matches database - user.comparePassword(req.body.password, function(error, isMatch) { - if (!isMatch && !error) { - return res.status(UNAUTHORIZED).send({ - message: 'Username or password does not match our records.' - }); - } + if (!isMatch) { + return res.status(UNAUTHORIZED).send({ + message: 'Username or password does not match our records.' + }); + } - if (user.accessLevel === membershipState.BANNED) { - return res - .status(UNAUTHORIZED) - .send({ - message: 'The account with email ' + - req.body.email + - ' is banned', - }); - } + if (!user.emailVerified) { + return res + .status(UNAUTHORIZED) + .send({ message: `The email ${req.body.email} has not been verified` }); + } - // Check if the user's email has been verified - if (!user.emailVerified) { - return res - .status(UNAUTHORIZED) - .send({ message: `The email ${req.body.email} has not been verified` }); - } + if (user.accessLevel === membershipState.BANNED) { + return res.status(UNAUTHORIZED).send({ message: `Account ${email} is banned lol` }); + } - // If the username and password matches the database, assign and - // return a jwt token - const jwtOptions = { - expiresIn: '2h' - }; + // Handle Page Reset + if (checkIfPageCountResets(user.lastLogin)) { + user.pagesPrinted = 0; + } + user.lastLogin = new Date(); + await user.save(); - // check here to see if we should reset the pagecount. If so, do it - if (checkIfPageCountResets(user.lastLogin)) { - user.pagesPrinted = 0; - } + const token = jwt.sign({ + _id: user._id, + accessLevel: user.accessLevel, + firstName: user.firstName, + lastName: user.lastName, + email: user.email, + accessLevel: user.accessLevel, + pagesPrinted: user.pagesPrinted, + _id: user._id + }, config.secretKey, { expiresIn: '2h' }); + + // Create audit log on successful sign-in + AuditLog.create({ + userId: user._id, + action: AuditLogActions.LOG_IN, + details: { email: user.email } + }).catch(logger.error); - // set last login date here!!!! - user.lastLogin = new Date(); - - - // Include fields from the User model that should - // be passed to the JSON Web Token (JWT) - const userToBeSigned = { - firstName: user.firstName, - lastName: user.lastName, - email: user.email, - accessLevel: user.accessLevel, - pagesPrinted: user.pagesPrinted, - _id: user._id - }; - user - .save() - .then(() => { - const token = jwt.sign( - userToBeSigned, config.secretKey, jwtOptions - ); - // Create audit log on successful sign-in - AuditLog.create({ - userId: user._id, - action: AuditLogActions.LOG_IN, - details: { email: user.email } - }).catch(logger.error); - - res.json({ token: 'JWT ' + token }); - }) - .catch((error) => { - logger.error('unable to login user', error); - res.sendStatus(SERVER_ERROR); - }); - }); - }); + res.json({ token: `JWT ${token}` }); + + } catch (error) { + logger.error('unable to login user', error); + res.sendStatus(SERVER_ERROR); + } }); // Verifies the users session if they have an active jwtToken. diff --git a/api/main_endpoints/util/userHelpers.js b/api/main_endpoints/util/userHelpers.js index 3cfcd7f59..c9e0c3c0f 100644 --- a/api/main_endpoints/util/userHelpers.js +++ b/api/main_endpoints/util/userHelpers.js @@ -186,22 +186,17 @@ async function findPasswordReset(resetToken) { * reset */ function checkIfPageCountResets(lastLogin) { - if (!lastLogin) return false; + if (!lastLogin) return true; // New users should probably start fresh - let oldDate = new Date(lastLogin.getTime()); - - // this returns "right now" when called - // to unit test, we mock when "right now" is - // - // by mocking, we can have `new Date` return - // tomorrow, last week etc const now = new Date(); - const oneWeekInMilliseconds = 7 * 24 * 60 * 60 * 1000; - // reset if users last login was >= week ago OR there was a sunday between the last login and now - const lastLoginWasOverOneWeekAgo = now.getTime() - oldDate.getTime() >= oneWeekInMilliseconds; - const aSundayHasPassedSinceLastLogin = oldDate.getDay() > now.getDay(); - return lastLoginWasOverOneWeekAgo || aSundayHasPassedSinceLastLogin; + // Find the most recent Sunday at 00:00:00 + const lastSunday = new Date(now); + lastSunday.setHours(0, 0, 0, 0); + lastSunday.setDate(now.getDate() - now.getDay()); + + // If they logged in BEFORE the most recent Sunday, reset! + return lastLogin.getTime() < lastSunday.getTime(); } /**