Users too

This commit is contained in:
rijkvanzanten
2020-07-09 13:38:08 -04:00
parent b8849bcafb
commit 306a7be75d
2 changed files with 38 additions and 49 deletions

View File

@@ -6,25 +6,21 @@ import * as UsersService from '../services/users';
import Joi from '@hapi/joi';
import { InvalidPayloadException, InvalidCredentialsException } from '../exceptions';
import useCollection from '../middleware/use-collection';
import * as ActivityService from '../services/activity';
const router = express.Router();
router.post(
'/',
useCollection('directus_users'),
sanitizeQuery,
validateQuery,
asyncHandler(async (req, res) => {
const item = await UsersService.createUser(req.body, req.sanitizedQuery);
ActivityService.createActivity({
action: ActivityService.Action.CREATE,
collection: req.collection,
item: item.id,
const primaryKey = await UsersService.createUser(req.body, {
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
userAgent: req.get('user-agent'),
user: req.user,
});
const item = await UsersService.readUser(primaryKey, req.sanitizedQuery);
return res.json({ data: item });
})
);
@@ -36,7 +32,6 @@ router.get(
validateQuery,
asyncHandler(async (req, res) => {
const item = await UsersService.readUsers(req.sanitizedQuery);
return res.json({ data: item });
})
);
@@ -77,17 +72,13 @@ router.patch(
throw new InvalidCredentialsException();
}
const item = await UsersService.updateUser(req.user, req.body, req.sanitizedQuery);
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: req.collection,
item: item.id,
const primaryKey = await UsersService.updateUser(req.user, req.body, {
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
userAgent: req.get('user-agent'),
user: req.user,
});
const item = await UsersService.readUser(primaryKey, req.sanitizedQuery);
return res.json({ data: item });
})
);
@@ -95,18 +86,15 @@ router.patch(
router.patch(
'/:pk',
useCollection('directus_users'),
sanitizeQuery,
validateQuery,
asyncHandler(async (req, res) => {
const item = await UsersService.updateUser(req.params.pk, req.body, req.sanitizedQuery);
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: req.collection,
item: item.id,
const primaryKey = await UsersService.updateUser(req.params.pk, req.body, {
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
userAgent: req.get('user-agent'),
user: req.user,
});
const item = await UsersService.readUser(primaryKey, req.sanitizedQuery);
return res.json({ data: item });
})
);
@@ -115,15 +103,10 @@ router.delete(
'/:pk',
useCollection('directus_users'),
asyncHandler(async (req, res) => {
await UsersService.deleteUser(req.params.pk);
ActivityService.createActivity({
action: ActivityService.Action.DELETE,
collection: req.collection,
item: req.params.pk,
await UsersService.deleteUser(req.params.pk, {
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
userAgent: req.get('user-agent'),
user: req.user,
});
return res.status(200).end();
@@ -141,7 +124,11 @@ router.post(
asyncHandler(async (req, res) => {
const { error } = inviteSchema.validate(req.body);
if (error) throw new InvalidPayloadException(error.message);
await UsersService.inviteUser(req.body.email, req.body.role);
await UsersService.inviteUser(req.body.email, req.body.role, {
ip: req.ip,
userAgent: req.get('user-agent'),
user: req.user,
});
res.end();
})
);

View File

@@ -1,14 +1,13 @@
import { Query } from '../types/query';
import * as ItemsService from './items';
import jwt from 'jsonwebtoken';
import { sendInviteMail } from '../mail';
import database from '../database';
import argon2 from 'argon2';
import { InvalidPayloadException } from '../exceptions';
import { Accountability, Query } from '../types';
export const createUser = async (data: Record<string, any>, query?: Query) => {
const primaryKey = await ItemsService.createItem('directus_users', data);
return await ItemsService.readItem('directus_users', primaryKey, query);
export const createUser = async (data: Record<string, any>, accountability: Accountability) => {
return await ItemsService.createItem('directus_users', data, accountability);
};
export const readUsers = async (query?: Query) => {
@@ -19,23 +18,26 @@ export const readUser = async (pk: string | number, query?: Query) => {
return await ItemsService.readItem('directus_users', pk, query);
};
export const updateUser = async (pk: string | number, data: Record<string, any>, query?: Query) => {
export const updateUser = async (
pk: string | number,
data: Record<string, any>,
accountability: Accountability
) => {
/**
* @todo
* Remove "other" refresh token sessions when changing password to enforce "logout everywhere" on password change
*
* Maybe make this an option?
*/
const primaryKey = await ItemsService.updateItem('directus_users', pk, data);
return await ItemsService.readItem('directus_users', primaryKey, query);
return await ItemsService.updateItem('directus_users', pk, data, accountability);
};
export const deleteUser = async (pk: string | number) => {
await ItemsService.deleteItem('directus_users', pk);
export const deleteUser = async (pk: string | number, accountability: Accountability) => {
await ItemsService.deleteItem('directus_users', pk, accountability);
};
export const inviteUser = async (email: string, role: string) => {
await createUser({ email, role, status: 'invited' });
export const inviteUser = async (email: string, role: string, accountability: Accountability) => {
await createUser({ email, role, status: 'invited' }, accountability);
const payload = { email };
const token = jwt.sign(payload, process.env.SECRET, { expiresIn: '7d' });
@@ -45,7 +47,7 @@ export const inviteUser = async (email: string, role: string) => {
};
export const acceptInvite = async (token: string, password: string) => {
const { email } = jwt.verify(token, process.env.SECRET) as Record<string, any>;
const { email } = jwt.verify(token, process.env.SECRET) as { email: string };
const user = await database
.select('id', 'status')
.from('directus_users')