Add payload processing on item create

This commit is contained in:
rijkvanzanten
2020-06-24 17:38:42 -04:00
parent 368e102906
commit 21155b2db8
2 changed files with 73 additions and 6 deletions

View File

@@ -0,0 +1,65 @@
/**
* Will check the fields system table for any special operations that need to be done on the field
* value, this can include hashing the value or generating a UUID
*/
import { RequestHandler } from 'express';
import asyncHandler from 'express-async-handler';
import { FieldInfo } from '../types/field';
import bcrypt from 'bcrypt';
type Operation = 'create' | 'update';
/**
* @TODO
*
* This needs a bit of extra thinking.
* - There's a difference between update / create payload processing
* - Some processing types need the whole payload (slug)
* - What happens for fields that aren't in the payload but need to be set on create?
*/
const processPayload = (operation: Operation) => {
const middleware: RequestHandler = asyncHandler(async (req, res, next) => {
// Get the fields that have a special operation associated with them
const fieldsInPayload = Object.keys(req.body);
const fieldInfoForFields = await req.loaders.fields.loadMany(
fieldsInPayload.map((field) => ({
collection: req.collection,
field: field,
}))
);
const specialFields = fieldInfoForFields.filter((field) => {
if (field instanceof Error) return false;
return field.special !== null;
}) as FieldInfo[];
for (const field of specialFields) {
req.body[field.field] = await processField(req.collection, field, req.body, operation);
}
next();
});
return middleware;
};
async function processField(
collection: string,
field: FieldInfo,
payload: Record<string, any>,
operation: Operation
) {
switch (field.special) {
case 'hash':
return await hash(payload[field.field]);
}
}
async function hash(value: string | number) {
return await bcrypt.hash(value, Number(process.env.SALT_ROUNDS));
}
export default processPayload;

View File

@@ -2,15 +2,17 @@ import express from 'express';
import asyncHandler from 'express-async-handler';
import { createItem, readItems, readItem, updateItem, deleteItem } from '../services/items';
import sanitizeQuery from '../middleware/sanitize-query';
import collectionExists from '../middleware/collection-exists';
import validateCollection from '../middleware/validate-collection';
import validateQuery from '../middleware/validate-query';
import * as MetaService from '../services/meta';
import processPayload from '../middleware/process-payload';
const router = express.Router();
router.post(
'/:collection',
collectionExists,
validateCollection,
processPayload('create'),
asyncHandler(async (req, res) => {
await createItem(req.params.collection, req.body);
res.status(200).end();
@@ -19,7 +21,7 @@ router.post(
router.get(
'/:collection',
collectionExists,
validateCollection,
sanitizeQuery,
validateQuery,
asyncHandler(async (req, res) => {
@@ -37,7 +39,7 @@ router.get(
router.get(
'/:collection/:pk',
collectionExists,
validateCollection,
asyncHandler(async (req, res) => {
const record = await readItem(req.params.collection, req.params.pk);
@@ -49,7 +51,7 @@ router.get(
router.patch(
'/:collection/:pk',
collectionExists,
validateCollection,
asyncHandler(async (req, res) => {
await updateItem(req.params.collection, req.params.pk, req.body);
return res.status(200).end();
@@ -58,7 +60,7 @@ router.patch(
router.delete(
'/:collection/:pk',
collectionExists,
validateCollection,
asyncHandler(async (req, res) => {
await deleteItem(req.params.collection, req.params.pk);
return res.status(200).end();