chore: make everything async instead of manual promise chaining

This commit is contained in:
Paul Bienkowski 2020-11-20 11:30:12 +01:00
parent bb2b569abe
commit 0b8fed3e27
9 changed files with 242 additions and 248 deletions

9
_helpers/wrapRoute.js Normal file
View file

@ -0,0 +1,9 @@
const wrapRoute = (fn) => async (req, res, next) => {
try {
return await fn(req, res);
} catch (err) {
next(err);
}
};
module.exports = wrapRoute;

View file

@ -1,6 +1,4 @@
module.exports = validateRequest; const validateRequest = (schema) => (req, res, next) => {
function validateRequest(req, next, schema) {
console.log('validateRequest'); console.log('validateRequest');
const options = { const options = {
@ -16,4 +14,6 @@ function validateRequest(req, next, schema) {
req.body = value; req.body = value;
next(); next();
} }
} };
module.exports = validateRequest;

View file

@ -1,93 +1,78 @@
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const Joi = require('joi'); const Joi = require('joi');
const wrapRoute = require('../_helpers/wrapRoute');
const validateRequest = require('../_middleware/validate-request'); const validateRequest = require('../_middleware/validate-request');
const accountService = require('./account.service'); const accountService = require('./account.service');
// routes router.post(
router.post('/register', registerSchema, register); '/register',
router.post('/verify-email', verifyEmailSchema, verifyEmail); validateRequest(
router.post('/forgot-password', forgotPasswordSchema, forgotPassword); Joi.object({
router.post('/validate-reset-token', validateResetTokenSchema, validateResetToken);
router.post('/reset-password', resetPasswordSchema, resetPassword);
module.exports = router;
function registerSchema(req, res, next) {
const schema = Joi.object({
username: Joi.string().required(), username: Joi.string().required(),
email: Joi.string().email().required(), email: Joi.string().email().required(),
password: Joi.string().min(6).required(), password: Joi.string().min(6).required(),
confirmPassword: Joi.string().valid(Joi.ref('password')).required(), confirmPassword: Joi.string().valid(Joi.ref('password')).required(),
}); }),
),
wrapRoute(async (req, res) => {
await accountService.register(req.body, req.get('origin'));
res.json({ message: 'Registration successful, please check your email for verification instructions' });
}),
);
validateRequest(req, next, schema); router.post(
} '/verify-email',
validateRequest(
function register(req, res, next) { Joi.object({
accountService
.register(req.body, req.get('origin'))
.then(() => res.json({ message: 'Registration successful, please check your email for verification instructions' }))
.catch((err) => {
console.log(err);
next(err);
});
}
function verifyEmailSchema(req, res, next) {
const schema = Joi.object({
token: Joi.string().required(), token: Joi.string().required(),
}); }),
validateRequest(req, next, schema); ),
} wrapRoute(async (req, res) => {
await accountService.verifyEmail(req.body);
res.json({ message: 'Verification successful, you can now login' });
}),
);
function verifyEmail(req, res, next) { router.post(
accountService '/forgot-password',
.verifyEmail(req.body) validateRequest(
.then(() => res.json({ message: 'Verification successful, you can now login' })) Joi.object({
.catch(next);
}
function forgotPasswordSchema(req, res, next) {
const schema = Joi.object({
email: Joi.string().email().required(), email: Joi.string().email().required(),
}); }),
validateRequest(req, next, schema); ),
} wrapRoute(async (req, res) => {
await accountService.forgotPassword(req.body, req.get('origin'));
res.json({ message: 'Please check your email for password reset instructions' });
}),
);
function forgotPassword(req, res, next) { router.post(
accountService '/validate-reset-token',
.forgotPassword(req.body, req.get('origin')) validateRequest(
.then(() => res.json({ message: 'Please check your email for password reset instructions' })) Joi.object({
.catch(next);
}
function validateResetTokenSchema(req, res, next) {
const schema = Joi.object({
token: Joi.string().required(), token: Joi.string().required(),
}); }),
validateRequest(req, next, schema); ),
} wrapRoute(async (req, res) => {
await accountService.validateResetToken(req.body);
res.json({ message: 'Token is valid' });
}),
);
function validateResetToken(req, res, next) { router.post(
accountService '/reset-password',
.validateResetToken(req.body) validateRequest(
.then(() => res.json({ message: 'Token is valid' })) Joi.object({
.catch(next);
}
function resetPasswordSchema(req, res, next) {
const schema = Joi.object({
token: Joi.string().required(), token: Joi.string().required(),
password: Joi.string().min(6).required(), password: Joi.string().min(6).required(),
confirmPassword: Joi.string().valid(Joi.ref('password')).required(), confirmPassword: Joi.string().valid(Joi.ref('password')).required(),
}); }),
validateRequest(req, next, schema); ),
} wrapRoute(async (req, res) => {
await accountService.resetPassword(req.body);
res.json({ message: 'Password reset successful, you can now login' });
}),
);
function resetPassword(req, res, next) { module.exports = router;
accountService
.resetPassword(req.body)
.then(() => res.json({ message: 'Password reset successful, you can now login' }))
.catch(next);
}

View file

@ -9,20 +9,21 @@ passport.use(
usernameField: 'user[email]', usernameField: 'user[email]',
passwordField: 'user[password]', passwordField: 'user[password]',
}, },
function (email, password, done) { async function (email, password, done) {
User.findOne({ email: email }) try {
.then(function (user) { const user = await User.findOne({ email: email });
if (!user || !user.validPassword(password)) { if (!user || !user.validPassword(password)) {
return done(null, false, { errors: { 'email or password': 'is invalid' } }); return done(null, false, { errors: { 'email or password': 'is invalid' } });
} }
if (user && user.needsEmailValidation) { if (user.needsEmailValidation) {
return done(null, false, { errors: { 'E-Mail-Bestätigung': 'noch nicht erfolgt' } }); return done(null, false, { errors: { 'E-Mail-Bestätigung': 'noch nicht erfolgt' } });
} }
return done(null, user); return done(null, user);
}) } catch (err) {
.catch(done); done(err);
}
}, },
), ),
); );

View file

@ -31,14 +31,9 @@ ArticleSchema.methods.slugify = function () {
this.slug = slug(this.title) + '-' + ((Math.random() * Math.pow(36, 6)) | 0).toString(36); this.slug = slug(this.title) + '-' + ((Math.random() * Math.pow(36, 6)) | 0).toString(36);
}; };
ArticleSchema.methods.updateFavoriteCount = function () { ArticleSchema.methods.updateFavoriteCount = async function () {
const article = this; this.favoritesCount = await User.count({ favorites: { $in: [this._id] } });
return await this.save();
return User.count({ favorites: { $in: [article._id] } }).then(function (count) {
article.favoritesCount = count;
return article.save();
});
}; };
ArticleSchema.methods.toJSONFor = function (user) { ArticleSchema.methods.toJSONFor = function (user) {

View file

@ -1,12 +1,13 @@
const router = require('express').Router(); const router = require('express').Router();
const mongoose = require('mongoose'); const mongoose = require('mongoose');
const User = mongoose.model('User'); const User = mongoose.model('User');
const wrapRoute = require('../../_helpers/wrapRoute');
const auth = require('../auth'); const auth = require('../auth');
// Preload user profile on routes with ':username' // Preload user profile on routes with ':username'
router.param('username', function (req, res, next, username) { router.param('username', async function (req, res, next, username) {
User.findOne({ username: username }) try {
.then(function (user) { const user = await User.findOne({ username: username });
if (!user) { if (!user) {
return res.sendStatus(404); return res.sendStatus(404);
} }
@ -14,54 +15,58 @@ router.param('username', function (req, res, next, username) {
req.profile = user; req.profile = user;
return next(); return next();
}) } catch (err) {
.catch(next); next(err);
}
}); });
router.get('/:username', auth.optional, function (req, res, next) { router.get(
if (req.payload) { '/:username',
User.findById(req.payload.id).then(function (user) { auth.optional,
wrapRoute(async (req, res) => {
if (!req.payload) {
return res.json({ profile: req.profile.toProfileJSONFor(false) });
}
const user = await User.findById(req.payload.id);
if (!user) { if (!user) {
return res.json({ profile: req.profile.toProfileJSONFor(false) }); return res.json({ profile: req.profile.toProfileJSONFor(false) });
} }
return res.json({ profile: req.profile.toProfileJSONFor(user) }); return res.json({ profile: req.profile.toProfileJSONFor(user) });
}); }),
} else { );
return res.json({ profile: req.profile.toProfileJSONFor(false) });
}
});
router.post('/:username/follow', auth.required, function (req, res, next) { router.post(
'/:username/follow',
auth.required,
wrapRoute(async (req, res) => {
const profileId = req.profile._id; const profileId = req.profile._id;
User.findById(req.payload.id) const user = await User.findById(req.payload.id);
.then(function (user) {
if (!user) { if (!user) {
return res.sendStatus(401); return res.sendStatus(401);
} }
return user.follow(profileId).then(function () { await user.follow(profileId);
return res.json({ profile: req.profile.toProfileJSONFor(user) }); return res.json({ profile: req.profile.toProfileJSONFor(user) });
}); }),
}) );
.catch(next);
});
router.delete('/:username/follow', auth.required, function (req, res, next) { router.delete(
'/:username/follow',
auth.required,
wrapRoute(async (req, res) => {
const profileId = req.profile._id; const profileId = req.profile._id;
User.findById(req.payload.id) const user = User.findById(req.payload.id);
.then(function (user) {
if (!user) { if (!user) {
return res.sendStatus(401); return res.sendStatus(401);
} }
return user.unfollow(profileId).then(function () { await user.unfollow(profileId);
return res.json({ profile: req.profile.toProfileJSONFor(user) }); return res.json({ profile: req.profile.toProfileJSONFor(user) });
}); }),
}) );
.catch(next);
});
module.exports = router; module.exports = router;

View file

@ -1,15 +1,15 @@
const router = require('express').Router(); const router = require('express').Router();
const mongoose = require('mongoose'); const mongoose = require('mongoose');
const Track = mongoose.model('Track'); const Track = mongoose.model('Track');
const wrapRoute = require('../../_helpers/wrapRoute');
// return a list of tags // return a list of tags
router.get('/', function (req, res, next) { router.get(
Track.find() '/',
.distinct('tagList') wrapRoute(async (req, res) => {
.then(function (tags) { const tags = await Track.find().distinct('tagList');
return res.json({ tags: tags }); return res.json({ tags: tags });
}) }),
.catch(next); );
});
module.exports = router; module.exports = router;

View file

@ -8,14 +8,7 @@ const auth = require('../auth');
const currentTracks = new Map(); const currentTracks = new Map();
const TrackInfo = require('../../logic/TrackInfo'); const TrackInfo = require('../../logic/TrackInfo');
const { addPointsToTrack } = require('../../logic/tracks'); const { addPointsToTrack } = require('../../logic/tracks');
const wrapRoute = require('../../_helpers/wrapRoute');
const wrapRoute = (fn) => async (req, res, next) => {
try {
return await fn(req, res);
} catch (err) {
next(err);
}
};
// Preload track objects on routes with ':track' // Preload track objects on routes with ':track'
router.param('track', async (req, res, next, slug) => { router.param('track', async (req, res, next, slug) => {
@ -296,7 +289,10 @@ router.get(
); );
// update track // update track
router.put('/:track', auth.required, async function (req, res, next) { router.put(
'/:track',
auth.required,
wrapRoute(async (req, res) => {
const user = await User.findById(req.payload.id); const user = await User.findById(req.payload.id);
if (req.track.author._id.toString() !== req.payload.id.toString()) { if (req.track.author._id.toString() !== req.payload.id.toString()) {
@ -331,7 +327,8 @@ router.put('/:track', auth.required, async function (req, res, next) {
const track = await req.track.save(); const track = await req.track.save();
return res.json({ track: track.toJSONFor(user) }); return res.json({ track: track.toJSONFor(user) });
}); }),
);
// delete track // delete track
router.delete( router.delete(

View file

@ -2,23 +2,27 @@ const mongoose = require('mongoose');
const router = require('express').Router(); const router = require('express').Router();
const passport = require('passport'); const passport = require('passport');
const User = mongoose.model('User'); const User = mongoose.model('User');
const wrapRoute = require('../../_helpers/wrapRoute');
const auth = require('../auth'); const auth = require('../auth');
router.get('/user', auth.required, function (req, res, next) { router.get(
User.findById(req.payload.id) '/user',
.then(function (user) { auth.required,
wrapRoute(async (req, res) => {
const user = await User.findById(req.payload.id);
if (!user) { if (!user) {
return res.sendStatus(401); return res.sendStatus(401);
} }
return res.json({ user: user.toAuthJSON() }); return res.json({ user: user.toAuthJSON() });
}) }),
.catch(next); );
});
router.put('/user', auth.required, function (req, res, next) { router.put(
User.findById(req.payload.id) '/user',
.then(function (user) { auth.required,
wrapRoute(async (req, res) => {
const user = await User.findById(req.payload.id);
if (!user) { if (!user) {
return res.sendStatus(401); return res.sendStatus(401);
} }
@ -43,12 +47,10 @@ router.put('/user', auth.required, function (req, res, next) {
user.setPassword(req.body.user.password); user.setPassword(req.body.user.password);
} }
return user.save().then(function () { await user.save();
return res.json({ user: user.toAuthJSON() }); return res.json({ user: user.toAuthJSON() });
}); }),
}) );
.catch(next);
});
router.post('/users/login', function (req, res, next) { router.post('/users/login', function (req, res, next) {
if (!req.body.user.email) { if (!req.body.user.email) {