From 6e4c81617da63e77a5ba7cee9a8088f1199896d7 Mon Sep 17 00:00:00 2001 From: raclim Date: Tue, 23 Apr 2024 12:35:41 -0400 Subject: [PATCH 1/4] refactor getUser function to async/await --- client/modules/User/actions.js | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/client/modules/User/actions.js b/client/modules/User/actions.js index 8e05a681f3..2a11d9ca12 100644 --- a/client/modules/User/actions.js +++ b/client/modules/User/actions.js @@ -91,24 +91,23 @@ export function validateAndSignUpUser(formValues) { } export function getUser() { - return (dispatch) => { - apiClient - .get('/session') - .then((response) => { - dispatch(authenticateUser(response.data)); - dispatch({ - type: ActionTypes.SET_PREFERENCES, - preferences: response.data.preferences - }); - setLanguage(response.data.preferences.language, { - persistPreference: false - }); - }) - .catch((error) => { - const { response } = error; - const message = response.message || response.data.error; - dispatch(authError(message)); + return async (dispatch) => { + try { + const response = await apiClient.get('/session'); + const { data } = response; + + dispatch(authenticateUser(data)); + dispatch({ + type: ActionTypes.SET_PREFERENCES, + preferences: data.preferences }); + setLanguage(data.preferences.language, { persistPreference: false }); + } catch (error) { + const message = error.response + ? error.response.data.error || error.response.message + : 'Unknown error.'; + dispatch(authError(message)); + } }; } From 616b1fd3758b79b15aa70eb691b8a7cd893cd182 Mon Sep 17 00:00:00 2001 From: raclim Date: Tue, 23 Apr 2024 12:36:13 -0400 Subject: [PATCH 2/4] refactor mail utils to async/await --- server/utils/mail.js | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/server/utils/mail.js b/server/utils/mail.js index 3c17411c5a..e01d976799 100644 --- a/server/utils/mail.js +++ b/server/utils/mail.js @@ -18,15 +18,12 @@ class Mail { }; } - sendMail(mailOptions) { - return new Promise((resolve, reject) => { - this.client.sendMail(mailOptions, (err, info) => { - resolve(err, info); - }); - }); + async sendMail(mailOptions) { + const response = await this.client.sendMail(mailOptions); + return response; } - dispatchMail(data, callback) { + async send(data) { const mailOptions = { to: data.to, subject: data.subject, @@ -34,13 +31,8 @@ class Mail { html: data.html }; - return this.sendMail(mailOptions).then((err, res) => { - callback(err, res); - }); - } - - send(data, callback) { - return this.dispatchMail(data, callback); + const response = await this.sendMail(mailOptions); + return response; } } From 3e06e705372e3f61e90479659f3196938eaceaa2 Mon Sep 17 00:00:00 2001 From: raclim Date: Tue, 23 Apr 2024 12:36:49 -0400 Subject: [PATCH 3/4] refactor local strategy is passport to async/await --- server/config/passport.js | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/server/config/passport.js b/server/config/passport.js index 29d38df139..b4995cd4bf 100644 --- a/server/config/passport.js +++ b/server/config/passport.js @@ -35,26 +35,31 @@ passport.deserializeUser((id, done) => { * Sign in using Email/Username and Password. */ passport.use( - new LocalStrategy({ usernameField: 'email' }, (email, password, done) => { - User.findByEmailOrUsername(email) - .then((user) => { + new LocalStrategy( + { usernameField: 'email' }, + async (email, password, done) => { + try { + const user = await User.findByEmailOrUsername(email); + if (!user) { - done(null, false, { msg: `Email ${email} not found.` }); - return; + return done(null, false, { msg: `Email ${email} not found.` }); } else if (user.banned) { - done(null, false, { msg: accountSuspensionMessage }); - return; + return done(null, false, { msg: 'Your account has been suspended.' }); } - user.comparePassword(password).then((isMatch) => { - if (isMatch) { - done(null, user); - } else { - done(null, false, { msg: 'Invalid email or password.' }); - } - }); - }) - .catch((err) => done(null, false, { msg: err })); - }) + + const isMatch = await user.comparePassword(password); + + if (isMatch) { + return done(null, user); + } else { // eslint-disable-line + return done(null, false, { msg: 'Invalid email or password' }); + } + } catch (err) { + console.error(err); + return done(null, false, { msg: err }); + } + } + ) ); /** From 8022ee1e0333045729fb14a49c011768bc095ade Mon Sep 17 00:00:00 2001 From: raclim Date: Tue, 23 Apr 2024 12:37:22 -0400 Subject: [PATCH 4/4] refactor createUser to async/await --- server/controllers/user.controller.js | 55 ++++++++++++++++----------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/server/controllers/user.controller.js b/server/controllers/user.controller.js index 52bd5a49cf..7efd7693df 100644 --- a/server/controllers/user.controller.js +++ b/server/controllers/user.controller.js @@ -43,6 +43,16 @@ export async function createUser(req, res) { try { const { username, email, password } = req.body; const emailLowerCase = email.toLowerCase(); + const existingUser = await User.findByEmailAndUsername(email, username); + if (existingUser) { + const fieldInUse = + existingUser.email.toLowerCase() === emailLowerCase + ? 'Email' + : 'Username'; + res.status(422).send({ error: `${fieldInUse} is in use` }); + return; + } + const EMAIL_VERIFY_TOKEN_EXPIRY_TIME = Date.now() + 3600000 * 24; // 24 hours const token = await generateToken(); const user = new User({ @@ -53,34 +63,35 @@ export async function createUser(req, res) { verifiedToken: token, verifiedTokenExpires: EMAIL_VERIFY_TOKEN_EXPIRY_TIME }); - const existingUser = await User.findByEmailAndUsername(email, username); - if (existingUser) { - const fieldInUse = - existingUser.email.toLowerCase() === emailLowerCase - ? 'Email' - : 'Username'; - res.status(422).send({ error: `${fieldInUse} is in use` }); - return; - } + await user.save(); - req.logIn(user, (loginErr) => { + + req.logIn(user, async (loginErr) => { if (loginErr) { - throw loginErr; + console.error(loginErr); + res.status(500).json({ error: 'Failed to log in user.' }); + return; } - }); - const protocol = process.env.NODE_ENV === 'production' ? 'https' : 'http'; - const mailOptions = renderEmailConfirmation({ - body: { - domain: `${protocol}://${req.headers.host}`, - link: `${protocol}://${req.headers.host}/verify?t=${token}` - }, - to: req.user.email - }); + const protocol = process.env.NODE_ENV === 'production' ? 'https' : 'http'; + const mailOptions = renderEmailConfirmation({ + body: { + domain: `${protocol}://${req.headers.host}`, + link: `${protocol}://${req.headers.host}/verify?t=${token}` + }, + to: req.user.email + }); - await mail.send(mailOptions); - res.json(userResponse(req.user)); + try { + await mail.send(mailOptions); + res.json(userResponse(user)); + } catch (mailErr) { + console.error(mailErr); + res.status(500).json({ error: 'Failed to send verification email.' }); + } + }); } catch (err) { + console.error(err); res.status(500).json({ error: err }); } }