feat: invites (#967)

* stub invite endpoint

* feat: First pass invite UI

* feat: allow removing invite rows

* First pass: sending logic

* fix: label accessibility

* fix: add button submits
incorrect permissions
middleware flow error

* 💚

* Error handling, email filtering, tests

* Flow

* Add Invite to people page
Remove old Tip

* Add copy link to subdomain
This commit is contained in:
Tom Moor
2019-06-24 22:14:59 -07:00
committed by GitHub
parent f406faf08e
commit d5192acabf
21 changed files with 509 additions and 103 deletions

View File

@ -12,6 +12,7 @@ import { ValidationError } from '../errors';
import { Event, User, Team } from '../models';
import auth from '../middlewares/authentication';
import pagination from './middlewares/pagination';
import userInviter from '../commands/userInviter';
import { presentUser } from '../presenters';
import policy from '../policies';
@ -150,11 +151,6 @@ router.post('users.demote', auth(), async ctx => {
};
});
/**
* Suspend user
*
* Admin can suspend users to reduce the number of accounts on their billing plan
*/
router.post('users.suspend', auth(), async ctx => {
const admin = ctx.state.user;
const userId = ctx.body.id;
@ -176,12 +172,6 @@ router.post('users.suspend', auth(), async ctx => {
};
});
/**
* Activate user
*
* Admin can activate users to let them access resources. These users will also
* account towards the billing plan limits.
*/
router.post('users.activate', auth(), async ctx => {
const admin = ctx.state.user;
const userId = ctx.body.id;
@ -199,6 +189,20 @@ router.post('users.activate', auth(), async ctx => {
};
});
router.post('users.invite', auth(), async ctx => {
const { invites } = ctx.body;
ctx.assertPresent(invites, 'invites is required');
const user = ctx.state.user;
authorize(user, 'invite', User);
const invitesSent = await userInviter({ user, invites });
ctx.body = {
data: invitesSent,
};
});
router.post('users.delete', auth(), async ctx => {
const { confirmation } = ctx.body;
ctx.assertPresent(confirmation, 'confirmation is required');