Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 54 additions & 84 deletions api/main_endpoints/routes/Auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
21 changes: 8 additions & 13 deletions api/main_endpoints/util/userHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

/**
Expand Down
Loading