2018-07-28 17:13:19 -04:00
|
|
|
const express = require('express');
|
|
|
|
const router = express.Router();
|
|
|
|
const crypto = require('crypto');
|
|
|
|
|
2018-08-01 11:54:35 -04:00
|
|
|
const ModelPath = '../../models/';
|
2018-07-28 17:13:19 -04:00
|
|
|
const Invite = require(ModelPath + 'Invite.js');
|
|
|
|
const User = require(ModelPath + 'User.js');
|
|
|
|
|
2018-08-01 11:54:35 -04:00
|
|
|
const wrap = require('../../util/wrap.js');
|
|
|
|
const requireAuth = require('../../util/auth').requireAuth;
|
|
|
|
const verifyScope = require('../../util/verifyScope');
|
2019-01-02 14:20:10 -05:00
|
|
|
const verifyBody = require('../../util/verifyBody');
|
2018-07-28 17:13:19 -04:00
|
|
|
|
|
|
|
const createParams = [{name: 'scope', instance: Array}];
|
2019-01-02 14:20:10 -05:00
|
|
|
router.post('/create', requireAuth('invite.create'), verifyBody(createParams), wrap(async (req, res, next) => {
|
2018-07-28 17:13:19 -04:00
|
|
|
const scope = req.body.scope;
|
2018-08-01 17:11:08 -04:00
|
|
|
if (!scope.every(scope => verifyScope(req.scope, scope)))
|
2018-07-28 17:13:19 -04:00
|
|
|
return res.status(403).json({message: 'Requested scope exceeds own scope.'});
|
|
|
|
|
|
|
|
const invite = {
|
|
|
|
code: crypto.randomBytes(12).toString('hex'),
|
|
|
|
scope: scope,
|
|
|
|
issuer: req.username,
|
|
|
|
issued: Date.now(),
|
|
|
|
expires: req.body.expires
|
|
|
|
};
|
|
|
|
|
|
|
|
await Promise.all([
|
|
|
|
Invite.create(invite).catch(next),
|
2018-08-01 12:20:35 -04:00
|
|
|
User.updateOne({username: req.username}, {$inc: {inviteCount: 1}})
|
2018-07-28 17:13:19 -04:00
|
|
|
]);
|
|
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
message: 'Invite created.',
|
|
|
|
code: invite.code
|
|
|
|
});
|
|
|
|
}));
|
|
|
|
|
|
|
|
const deleteParams = [{name: 'code', type: 'string'}];
|
2019-01-02 14:20:10 -05:00
|
|
|
router.post('/delete', requireAuth('invite.delete'), verifyBody(deleteParams), wrap(async (req, res, next) => {
|
2018-07-28 17:13:19 -04:00
|
|
|
let query = {code: req.body.code};
|
|
|
|
|
|
|
|
// Users need a permission to delete invites other than their own
|
|
|
|
if (!verifyScope(req.scope, 'invite.delete.others'))
|
|
|
|
query.issuer = req.username;
|
|
|
|
|
|
|
|
// Find the invite
|
|
|
|
const invite = await Invite.findOne(query).catch(next);
|
|
|
|
if (!invite)
|
2018-08-01 17:11:08 -04:00
|
|
|
return res.status(422).json({message: 'Invite not found.'});
|
2018-07-28 17:13:19 -04:00
|
|
|
|
|
|
|
// Users need a permission to delete invites that have been used
|
|
|
|
if (!verifyScope(req.scope, 'invite.delete.used') && invite.used != null && invite.recipient != null)
|
|
|
|
return res.status(403).json({message: 'Forbidden to delete used invites.'});
|
|
|
|
|
|
|
|
await Invite.deleteOne({_id: invite._id}).catch(next);
|
|
|
|
res.status(200).json({message: 'Invite deleted.'});
|
|
|
|
}));
|
|
|
|
|
2018-08-01 17:11:08 -04:00
|
|
|
const getParams = [{name: 'code', type: 'string', optional: true}, {name: 'issuer', type: 'string', optional: true}];
|
2019-01-02 14:20:10 -05:00
|
|
|
router.get('/get', requireAuth('invite.get'), verifyBody(getParams), wrap(async (req, res, next) => {
|
2018-07-28 17:13:19 -04:00
|
|
|
let query = {};
|
|
|
|
|
|
|
|
// Users need a permission to list invites other than their own
|
|
|
|
if (!verifyScope(req.scope, 'invite.get.others'))
|
|
|
|
query.issuer = req.username;
|
2018-08-01 17:11:08 -04:00
|
|
|
else if (req.body.issuer)
|
|
|
|
query.issuer = req.body.issuer;
|
2018-07-28 17:13:19 -04:00
|
|
|
|
|
|
|
// Narrow down the query by code if specified
|
|
|
|
if (req.body.code)
|
|
|
|
query.code = req.body.code;
|
|
|
|
|
|
|
|
const invites = await Invite.find(query).catch(next);
|
|
|
|
res.status(200).json(invites);
|
|
|
|
}));
|
|
|
|
|
|
|
|
module.exports = router;
|