Track activity

This commit is contained in:
rijkvanzanten
2020-06-29 18:26:47 -04:00
parent 660f26c4ec
commit 6ffa166167
16 changed files with 401 additions and 105 deletions

92
package-lock.json generated
View File

@@ -231,6 +231,14 @@
"@hapi/hoek": "^9.0.0"
}
},
"@phc/format": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@phc/format/-/format-0.5.0.tgz",
"integrity": "sha512-JWtZ5P1bfXU0bAtTzCpOLYHDXuxSVdtL/oqz4+xa97h8w9E5IlVN333wugXVFv8vZ1hbXObKQf1ptXmFFcMByg==",
"requires": {
"safe-buffer": "^5.1.2"
}
},
"@slynova/flydrive": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@slynova/flydrive/-/flydrive-1.0.1.tgz",
@@ -267,12 +275,6 @@
"integrity": "sha512-8GAYQ1jDRUQkSpHzJUqXwAkYFOxuWAOGLhIR4aPd/Y/yL12Q/9m7LsKpHKlfKdNE/362Hc9wPI1Yh6opDfxVJg==",
"dev": true
},
"@types/bcrypt": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-3.0.0.tgz",
"integrity": "sha512-nohgNyv+1ViVcubKBh0+XiNJ3dO8nYu///9aJ4cgSqv70gBL+94SNy/iC2NLzKPT2Zt/QavrOkBVbZRLZmw6NQ==",
"dev": true
},
"@types/body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
@@ -647,6 +649,48 @@
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
},
"argon2": {
"version": "0.26.2",
"resolved": "https://registry.npmjs.org/argon2/-/argon2-0.26.2.tgz",
"integrity": "sha512-Tk9I/r3KIHCIHU5x2UawKsPi+g7MByAYnUZghXztQDXRp/997P31wa4qvdvokTaFBpsu6jOZACd+2qkBGGssRA==",
"requires": {
"@phc/format": "^0.5.0",
"node-addon-api": "^2.0.0",
"node-pre-gyp": "^0.14.0"
},
"dependencies": {
"node-addon-api": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.1.tgz",
"integrity": "sha512-2WVfwRfIr1AVn3dRq4yRc2Hn35ND+mPJH6inC6bjpYCZVrpXPB4j3T6i//OGVfqVsR1t/X/axRulDsheq4F0LQ=="
},
"node-pre-gyp": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz",
"integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==",
"requires": {
"detect-libc": "^1.0.2",
"mkdirp": "^0.5.1",
"needle": "^2.2.1",
"nopt": "^4.0.1",
"npm-packlist": "^1.1.6",
"npmlog": "^4.0.2",
"rc": "^1.2.7",
"rimraf": "^2.6.1",
"semver": "^5.3.0",
"tar": "^4.4.2"
}
},
"rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"requires": {
"glob": "^7.1.3"
}
}
}
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -882,42 +926,6 @@
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
},
"bcrypt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.0.tgz",
"integrity": "sha512-jB0yCBl4W/kVHM2whjfyqnxTmOHkCX4kHEa5nYKSoGeYe8YrjTYTc87/6bwt1g8cmV0QrbhKriETg9jWtcREhg==",
"requires": {
"node-addon-api": "^3.0.0",
"node-pre-gyp": "0.15.0"
},
"dependencies": {
"node-pre-gyp": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz",
"integrity": "sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==",
"requires": {
"detect-libc": "^1.0.2",
"mkdirp": "^0.5.3",
"needle": "^2.5.0",
"nopt": "^4.0.1",
"npm-packlist": "^1.1.6",
"npmlog": "^4.0.2",
"rc": "^1.2.7",
"rimraf": "^2.6.1",
"semver": "^5.3.0",
"tar": "^4.4.2"
}
},
"rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"requires": {
"glob": "^7.1.3"
}
}
}
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",

View File

@@ -29,7 +29,6 @@
"homepage": "https://github.com/directus/api-node#readme",
"devDependencies": {
"@types/atob": "^2.1.2",
"@types/bcrypt": "^3.0.0",
"@types/busboy": "^0.2.3",
"@types/express": "^4.17.6",
"@types/express-pino-logger": "^4.0.2",
@@ -68,8 +67,8 @@
"@slynova/flydrive": "^1.0.1",
"@slynova/flydrive-gcs": "^1.0.1",
"@slynova/flydrive-s3": "^1.0.1",
"argon2": "^0.26.2",
"atob": "^2.1.2",
"bcrypt": "^5.0.0",
"body-parser": "^1.19.0",
"busboy": "^0.3.1",
"camelcase": "^6.0.0",

View File

@@ -4,6 +4,7 @@ import sanitizeQuery from '../middleware/sanitize-query';
import validateQuery from '../middleware/validate-query';
import * as CollectionPresetsService from '../services/collection-presets';
import useCollection from '../middleware/use-collection';
import * as ActivityService from '../services/activity';
const router = express.Router();
@@ -11,11 +12,21 @@ router.post(
'/',
useCollection('directus_collection_presets'),
asyncHandler(async (req, res) => {
const records = await CollectionPresetsService.createCollectionPreset(
const record = await CollectionPresetsService.createCollectionPreset(
req.body,
res.locals.query
);
return res.json({ data: records });
ActivityService.createActivity({
action: ActivityService.Action.CREATE,
collection: 'directus_collection_presets',
item: record.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: record });
})
);
@@ -48,12 +59,22 @@ router.patch(
'/:pk',
useCollection('directus_collection_presets'),
asyncHandler(async (req, res) => {
const records = await CollectionPresetsService.updateCollectionPreset(
const record = await CollectionPresetsService.updateCollectionPreset(
req.params.pk,
req.body,
res.locals.query
);
return res.json({ data: records });
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: 'directus_collection_presets',
item: record.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: record });
})
);
@@ -62,6 +83,16 @@ router.delete(
useCollection('directus_collection_presets'),
asyncHandler(async (req, res) => {
await CollectionPresetsService.deleteCollectionPreset(req.params.pk);
ActivityService.createActivity({
action: ActivityService.Action.DELETE,
collection: 'directus_collection_presets',
item: req.params.pk,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.status(200).end();
})
);

View File

@@ -7,12 +7,14 @@ import * as FilesService from '../services/files';
import logger from '../logger';
import { InvalidPayloadException } from '../exceptions';
import useCollection from '../middleware/use-collection';
import * as ActivityService from '../services/activity';
const router = express.Router();
const multipartHandler = (operation: 'create' | 'update') =>
asyncHandler(async (req, res, next) => {
const busboy = new Busboy({ headers: req.headers });
const savedFiles: Record<string, any> = [];
/**
* The order of the fields in multipart/form-data is important. We require that all fields
@@ -53,9 +55,31 @@ const multipartHandler = (operation: 'create' | 'update') =>
try {
if (operation === 'create') {
await FilesService.createFile(payload, fileStream);
const file = await FilesService.createFile(payload, fileStream);
ActivityService.createActivity({
action: ActivityService.Action.UPLOAD,
collection: 'directus_files',
item: file.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
savedFiles.push(file);
} else {
await FilesService.updateFile(req.params.pk, payload, fileStream);
const file = await FilesService.updateFile(req.params.pk, payload, fileStream);
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: 'directus_files',
item: file.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
savedFiles.push(file);
}
} catch (err) {
busboy.emit('error', err);
@@ -67,7 +91,7 @@ const multipartHandler = (operation: 'create' | 'update') =>
});
busboy.on('finish', () => {
res.status(200).end();
res.status(200).json({ data: savedFiles });
});
return req.pipe(busboy);
@@ -101,13 +125,24 @@ router.patch(
'/:pk',
useCollection('directus_files'),
asyncHandler(async (req, res, next) => {
let file: Record<string, any>;
if (req.is('multipart/form-data')) {
await multipartHandler('update')(req, res, next);
file = await multipartHandler('update')(req, res, next);
} else {
await FilesService.updateFile(req.params.pk, req.body);
file = await FilesService.updateFile(req.params.pk, req.body);
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: 'directus_files',
item: file.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
}
return res.status(200).end();
return res.status(200).json({ data: file });
})
);

View File

@@ -2,8 +2,10 @@ import express from 'express';
import asyncHandler from 'express-async-handler';
import sanitizeQuery from '../middleware/sanitize-query';
import validateQuery from '../middleware/validate-query';
import * as FoldersService from '../services/folders';
import useCollection from '../middleware/use-collection';
import * as FoldersService from '../services/folders';
import * as ActivityService from '../services/activity';
import * as PayloadService from '../services/payload';
const router = express.Router();
@@ -11,8 +13,19 @@ router.post(
'/',
useCollection('directus_folders'),
asyncHandler(async (req, res) => {
const records = await FoldersService.createFolder(req.body, res.locals.query);
return res.json({ data: records });
const payload = await PayloadService.processValues('create', req.collection, req.body);
const record = await FoldersService.createFolder(payload, res.locals.query);
ActivityService.createActivity({
action: ActivityService.Action.CREATE,
collection: req.collection,
item: record.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: record });
})
);
@@ -42,12 +55,20 @@ router.patch(
'/:pk',
useCollection('directus_folders'),
asyncHandler(async (req, res) => {
const records = await FoldersService.updateFolder(
req.params.pk,
req.body,
res.locals.query
);
return res.json({ data: records });
const payload = await PayloadService.processValues('create', req.collection, req.body);
const record = await FoldersService.updateFolder(req.params.pk, payload, res.locals.query);
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: req.collection,
item: record.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: record });
})
);
@@ -56,6 +77,16 @@ router.delete(
useCollection('directus_folders'),
asyncHandler(async (req, res) => {
await FoldersService.deleteFolder(req.params.pk);
ActivityService.createActivity({
action: ActivityService.Action.DELETE,
collection: req.collection,
item: req.params.pk,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.status(200).end();
})
);

View File

@@ -7,6 +7,7 @@ import validateSingleton from '../middleware/validate-singleton';
import validateQuery from '../middleware/validate-query';
import * as MetaService from '../services/meta';
import * as PayloadService from '../services/payload';
import * as ActivityService from '../services/activity';
const router = express.Router();
@@ -16,8 +17,19 @@ router.post(
validateSingleton,
asyncHandler(async (req, res) => {
const payload = await PayloadService.processValues('create', req.collection, req.body);
await createItem(req.params.collection, payload);
res.status(200).end();
const item = await createItem(req.params.collection, payload);
ActivityService.createActivity({
action: ActivityService.Action.CREATE,
collection: req.collection,
/** @TODO don't forget to use real primary key here */
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
res.json({ data: item });
})
);
@@ -56,8 +68,18 @@ router.patch(
validateCollection,
asyncHandler(async (req, res) => {
const payload = await PayloadService.processValues('update', req.collection, req.body);
await updateItem(req.params.collection, req.params.pk, payload);
return res.status(200).end();
const item = await updateItem(req.params.collection, req.params.pk, payload);
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: req.collection,
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: item });
})
);
@@ -66,6 +88,16 @@ router.delete(
validateCollection,
asyncHandler(async (req, res) => {
await deleteItem(req.params.collection, req.params.pk);
ActivityService.createActivity({
action: ActivityService.Action.DELETE,
collection: req.collection,
item: req.params.pk,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.status(200).end();
})
);

View File

@@ -3,6 +3,7 @@ import asyncHandler from 'express-async-handler';
import sanitizeQuery from '../middleware/sanitize-query';
import validateQuery from '../middleware/validate-query';
import * as PermissionsService from '../services/permissions';
import * as ActivityService from '../services/activity';
import useCollection from '../middleware/use-collection';
const router = express.Router();
@@ -11,8 +12,18 @@ router.post(
'/',
useCollection('directus_permissions'),
asyncHandler(async (req, res) => {
const records = await PermissionsService.createPermission(req.body, res.locals.query);
return res.json({ data: records });
const item = await PermissionsService.createPermission(req.body, res.locals.query);
ActivityService.createActivity({
action: ActivityService.Action.CREATE,
collection: req.collection,
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: item });
})
);
@@ -22,8 +33,8 @@ router.get(
sanitizeQuery,
validateQuery,
asyncHandler(async (req, res) => {
const records = await PermissionsService.readPermissions(res.locals.query);
return res.json({ data: records });
const item = await PermissionsService.readPermissions(res.locals.query);
return res.json({ data: item });
})
);
@@ -42,12 +53,22 @@ router.patch(
'/:pk',
useCollection('directus_permissions'),
asyncHandler(async (req, res) => {
const records = await PermissionsService.updatePermission(
const item = await PermissionsService.updatePermission(
req.params.pk,
req.body,
res.locals.query
);
return res.json({ data: records });
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: req.collection,
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: item });
})
);
@@ -56,6 +77,16 @@ router.delete(
useCollection('directus_permissions'),
asyncHandler(async (req, res) => {
await PermissionsService.deletePermission(req.params.pk);
ActivityService.createActivity({
action: ActivityService.Action.DELETE,
collection: req.collection,
item: req.params.pk,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.status(200).end();
})
);

View File

@@ -4,6 +4,7 @@ import sanitizeQuery from '../middleware/sanitize-query';
import validateQuery from '../middleware/validate-query';
import * as RelationsService from '../services/relations';
import useCollection from '../middleware/use-collection';
import * as ActivityService from '../services/activity';
const router = express.Router();
@@ -11,8 +12,18 @@ router.post(
'/',
useCollection('directus_relations'),
asyncHandler(async (req, res) => {
const records = await RelationsService.createRelation(req.body, res.locals.query);
return res.json({ data: records });
const item = await RelationsService.createRelation(req.body, res.locals.query);
ActivityService.createActivity({
action: ActivityService.Action.CREATE,
collection: req.collection,
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: item });
})
);
@@ -42,12 +53,22 @@ router.patch(
'/:pk',
useCollection('directus_relations'),
asyncHandler(async (req, res) => {
const records = await RelationsService.updateRelation(
const item = await RelationsService.updateRelation(
req.params.pk,
req.body,
res.locals.query
);
return res.json({ data: records });
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: req.collection,
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: item });
})
);
@@ -56,6 +77,16 @@ router.delete(
useCollection('directus_relations'),
asyncHandler(async (req, res) => {
await RelationsService.deleteRelation(req.params.pk);
ActivityService.createActivity({
action: ActivityService.Action.DELETE,
collection: req.collection,
item: req.params.pk,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.status(200).end();
})
);

View File

@@ -4,6 +4,7 @@ import sanitizeQuery from '../middleware/sanitize-query';
import validateQuery from '../middleware/validate-query';
import * as RolesService from '../services/roles';
import useCollection from '../middleware/use-collection';
import * as ActivityService from '../services/activity';
const router = express.Router();
@@ -11,8 +12,18 @@ router.post(
'/',
useCollection('directus_roles'),
asyncHandler(async (req, res) => {
const records = await RolesService.createRole(req.body, res.locals.query);
return res.json({ data: records });
const item = await RolesService.createRole(req.body, res.locals.query);
ActivityService.createActivity({
action: ActivityService.Action.CREATE,
collection: req.collection,
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: item });
})
);
@@ -42,8 +53,18 @@ router.patch(
'/:pk',
useCollection('directus_roles'),
asyncHandler(async (req, res) => {
const records = await RolesService.updateRole(req.params.pk, req.body, res.locals.query);
return res.json({ data: records });
const item = await RolesService.updateRole(req.params.pk, req.body, res.locals.query);
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: req.collection,
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: item });
})
);
@@ -52,6 +73,16 @@ router.delete(
useCollection('directus_roles'),
asyncHandler(async (req, res) => {
await RolesService.deleteRole(req.params.pk);
ActivityService.createActivity({
action: ActivityService.Action.DELETE,
collection: req.collection,
item: req.params.pk,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.status(200).end();
})
);

View File

@@ -6,6 +6,7 @@ import * as UsersService from '../services/users';
import Joi from '@hapi/joi';
import { InvalidPayloadException } from '../exceptions';
import useCollection from '../middleware/use-collection';
import * as ActivityService from '../services/activity';
const router = express.Router();
@@ -13,8 +14,18 @@ router.post(
'/',
useCollection('directus_users'),
asyncHandler(async (req, res) => {
const records = await UsersService.createUser(req.body, res.locals.query);
return res.json({ data: records });
const item = await UsersService.createUser(req.body, res.locals.query);
ActivityService.createActivity({
action: ActivityService.Action.CREATE,
collection: req.collection,
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: item });
})
);
@@ -24,8 +35,18 @@ router.get(
sanitizeQuery,
validateQuery,
asyncHandler(async (req, res) => {
const records = await UsersService.readUsers(res.locals.query);
return res.json({ data: records });
const item = await UsersService.readUsers(res.locals.query);
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: req.collection,
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: item });
})
);
@@ -54,6 +75,16 @@ router.delete(
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,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.status(200).end();
})
);

View File

@@ -4,6 +4,7 @@ import sanitizeQuery from '../middleware/sanitize-query';
import validateQuery from '../middleware/validate-query';
import * as WebhooksService from '../services/webhooks';
import useCollection from '../middleware/use-collection';
import * as ActivityService from '../services/activity';
const router = express.Router();
@@ -11,8 +12,18 @@ router.post(
'/',
useCollection('directus_webhooks'),
asyncHandler(async (req, res) => {
const records = await WebhooksService.createWebhook(req.body, res.locals.query);
return res.json({ data: records });
const item = await WebhooksService.createWebhook(req.body, req.query);
ActivityService.createActivity({
action: ActivityService.Action.CREATE,
collection: req.collection,
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: item });
})
);
@@ -22,7 +33,7 @@ router.get(
sanitizeQuery,
validateQuery,
asyncHandler(async (req, res) => {
const records = await WebhooksService.readWebhooks(res.locals.query);
const records = await WebhooksService.readWebhooks(req.query);
return res.json({ data: records });
})
);
@@ -33,7 +44,7 @@ router.get(
sanitizeQuery,
validateQuery,
asyncHandler(async (req, res) => {
const record = await WebhooksService.readWebhook(req.params.pk, res.locals.query);
const record = await WebhooksService.readWebhook(req.params.pk, req.query);
return res.json({ data: record });
})
);
@@ -42,12 +53,18 @@ router.patch(
'/:pk',
useCollection('directus_webhooks'),
asyncHandler(async (req, res) => {
const records = await WebhooksService.updateWebhook(
req.params.pk,
req.body,
res.locals.query
);
return res.json({ data: records });
const item = await WebhooksService.updateWebhook(req.params.pk, req.body, req.query);
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: req.collection,
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: item });
})
);
@@ -56,6 +73,16 @@ router.delete(
useCollection('directus_webhooks'),
asyncHandler(async (req, res) => {
await WebhooksService.deleteWebhook(req.params.pk);
ActivityService.createActivity({
action: ActivityService.Action.DELETE,
collection: req.collection,
item: req.params.pk,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.status(200).end();
})
);

View File

@@ -1,6 +1,6 @@
import database from '../database';
import jwt from 'jsonwebtoken';
import bcrypt from 'bcrypt';
import argon2 from 'argon2';
import { InvalidCredentialsException } from '../exceptions';
export const authenticate = async (email: string, password?: string) => {
@@ -21,7 +21,7 @@ export const authenticate = async (email: string, password?: string) => {
* email to leak anywhere else.. We might have to make a dedicated "copy" of this function to
* signal the difference
*/
if (password !== undefined && (await bcrypt.compare(password, user.password)) === false) {
if (password !== undefined && (await argon2.verify(password, user.password)) === false) {
throw new InvalidCredentialsException();
}

View File

@@ -45,7 +45,7 @@ export const createFile = async (
}
await storage.disk(data.storage).put(data.filename_disk, stream as any);
await ItemsService.createItem('directus_files', payload, query);
return await ItemsService.createItem('directus_files', payload, query);
};
export const readFiles = async (query: Query) => {
@@ -64,13 +64,17 @@ export const updateFile = async (
query?: Query
) => {
const payload = await PayloadService.processValues('update', 'directus_files', data);
await ItemsService.updateItem('directus_files', pk, payload, query);
/**
* @TODO
* Handle changes in storage adapter -> going from local to S3 needs to delete from one, upload to the other
*/
/**
* @TODO
* Extract metadata here too
*/
if (stream) {
const file = await database
.select('storage', 'filename_disk')
@@ -81,6 +85,8 @@ export const updateFile = async (
// @todo type of stream in flydrive is wrong: https://github.com/Slynova-Org/flydrive/issues/145
await storage.disk(file.storage).put(file.filename_disk, stream as any);
}
return await ItemsService.updateItem('directus_files', pk, payload, query);
};
export const deleteFile = async (pk: string | number) => {

View File

@@ -76,7 +76,8 @@ export const updateItem = async (
data: Record<string, any>,
query: Query = {}
) => {
return await database(collection).update(data).where({ id: pk });
const result = await database(collection).update(data).where({ id: pk }).returning('id');
return readItem(collection, result[0], query);
};
export const deleteItem = async (collection: string, pk: number | string) => {

View File

@@ -6,7 +6,7 @@
*/
import { FieldInfo } from '../types/field';
import bcrypt from 'bcrypt';
import argon2 from 'argon2';
import { v4 as uuidv4 } from 'uuid';
import database from '../database';
import { clone } from 'lodash';
@@ -51,8 +51,10 @@ async function processField(
}
}
async function genHash(value: string | number) {
return await bcrypt.hash(value, Number(process.env.SALT_ROUNDS));
async function genHash(value?: string | number) {
if (!value) return;
return await argon2.hash(String(value));
}
async function genUUID(operation: 'create' | 'update') {

View File

@@ -3,7 +3,7 @@ import * as ItemsService from './items';
import jwt from 'jsonwebtoken';
import { sendInviteMail } from '../mail';
import database from '../database';
import bcrypt from 'bcrypt';
import argon2 from 'argon2';
import * as PayloadService from '../services/payload';
import { InvalidPayloadException } from '../exceptions';
@@ -55,7 +55,7 @@ export const acceptInvite = async (token: string, password: string) => {
throw new InvalidPayloadException(`Email address ${email} hasn't been invited.`);
}
const passwordHashed = await bcrypt.hash(password, Number(process.env.SALT_ROUNDS));
const passwordHashed = await argon2.hash(password);
await database('directus_users')
.update({ password: passwordHashed, status: 'active' })