Files
talk/routes/api/users/index.js
T
2017-11-02 17:16:57 -06:00

172 lines
4.5 KiB
JavaScript

const express = require('express');
const router = express.Router();
const UsersService = require('../../../services/users');
const mailer = require('../../../services/mailer');
const errors = require('../../../errors');
const authorization = require('../../../middleware/authorization');
const Limit = require('../../../services/limit');
router.get('/', authorization.needed('ADMIN', 'MODERATOR'), async (req, res, next) => {
const {
value = '',
field = 'created_at',
page = 1,
asc = 'false',
limit = 20 // Total Per Page
} = req.query;
try {
const queryOpts = {
sort: {[field]: (asc === 'true') ? 1 : -1},
skip: (page - 1) * limit,
limit
};
let [result, count] = await Promise.all([
UsersService
.search(value)
.sort(queryOpts.sort)
.skip(parseInt(queryOpts.skip))
.limit(parseInt(queryOpts.limit))
.lean(),
UsersService.search(value).count()
]);
res.json({
result,
limit: Number(limit),
count,
page: Number(page),
totalPages: Math.ceil(count / (limit === 0 ? 1 : limit))
});
} catch (e) {
next(e);
}
});
router.post('/:user_id/role', authorization.needed('ADMIN', 'MODERATOR'), async (req, res, next) => {
try {
await UsersService.addRoleToUser(req.params.user_id, req.body.role);
res.status(204).end();
} catch (e) {
next(e);
}
});
router.post('/:user_id/email', authorization.needed('ADMIN', 'MODERATOR'), async (req, res, next) => {
try {
let user = await UsersService.findById(req.params.user_id);
let localProfile = user.profiles.find((profile) => profile.provider === 'local');
if (!localProfile) {
return next(errors.ErrMissingEmail);
}
await mailer.sendSimple({
template: 'notification', // needed to know which template to render!
locals: { // specifies the template locals.
body: req.body.body
},
subject: req.body.subject,
to: localProfile.id // This only works if the user has registered via e-mail.
});
res.status(204).end();
} catch (e) {
next(e);
}
});
// create a local user.
router.post('/', async (req, res, next) => {
const {email, password, username} = req.body;
const redirectUri = req.header('X-Pym-Url') || req.header('Referer');
try {
let user = await UsersService.createLocalUser(email, password, username);
// Send an email confirmation. The Front end will know about the
// requireEmailConfirmation as it's included in the settings get endpoint.
await UsersService.sendEmailConfirmation(user, email, redirectUri);
res.status(201).json(user);
} catch (e) {
return next(e);
}
});
// This will allow 1 try every minute.
const resendRateLimiter = new Limit('/api/v1/users/resend-verify', 1, '1m');
// trigger an email confirmation re-send by a new user
router.post('/resend-verify', async (req, res, next) => {
const redirectUri = req.header('X-Pym-Url') || req.header('Referer');
let {email = ''} = req.body;
// Clean up and validate the email.
email = email.toLowerCase().trim();
if (email.length < 5) {
return next(errors.ErrMissingEmail);
}
// Check if we're past the rate limit, if we are, stop now. Otherwise, record
// this as an attempt to send a verification email.
try {
const tries = await resendRateLimiter.get(email);
if (tries > 0) {
throw errors.ErrMaxRateLimit;
}
await resendRateLimiter.test(email);
} catch (err) {
return next(err);
}
try {
const user = await UsersService.findLocalUser(email);
if (!user) {
throw errors.ErrNotFound;
}
await UsersService.sendEmailConfirmation(user, email, redirectUri);
res.status(204).end();
} catch (e) {
console.trace(e);
res.status(204).end();
}
});
// trigger an email confirmation re-send from the admin panel
router.post('/:user_id/email/confirm', authorization.needed('ADMIN', 'MODERATOR'), async (req, res, next) => {
const {
user_id
} = req.params;
try {
let user = await UsersService.findById(user_id);
if (!user) {
return next(errors.ErrNotFound);
}
// Find the first local profile.
let localProfile = user.profiles.find((profile) => profile.provider === 'local');
if (!localProfile) {
return next(errors.ErrMissingEmail);
}
// Send the email to the first local profile that was found.
await UsersService.sendEmailConfirmation(user, localProfile.id);
res.status(204).end();
} catch (e) {
return next(e);
}
});
module.exports = router;