Mime type validation for APIs

This commit is contained in:
Felix Kaspar 2023-12-21 22:52:05 +01:00
parent 3e10972efa
commit abc0f8cb8a
3 changed files with 33 additions and 21 deletions

View File

@ -8,6 +8,7 @@ import { Operator } from '@stirling-pdf/shared-operations/src/functions';
import { PdfFile } from '@stirling-pdf/shared-operations/src/wrappers/PdfFile';
import { respondWithPdfFiles } from 'utils/endpoint-utils';
import { Action } from '@stirling-pdf/shared-operations/declarations/Action';
import { JoiPDFFileSchema } from '@stirling-pdf/shared-operations/src/wrappers/PdfFileJoi';
router.post('/:func', upload.array("file"), async function(req: Request, res: Response) {
handleEndpoint(req, res);
@ -23,12 +24,12 @@ function handleEndpoint(req: Request, res: Response) {
return;
}
let pdfFiles: PdfFile[] = [];
if (Array.isArray(req.files))
pdfFiles = PdfFile.fromMulterFiles(req.files);
else {
pdfFiles = PdfFile.fromMulterFiles(Object.values(req.files).flatMap(va => va));
const validationResults = JoiPDFFileSchema.validate(req.files);
if(validationResults.error) {
res.status(400).json({error: "PDF validation failed", details: validationResults.error.message});
return;
}
const pdfFiles: PdfFile[] = validationResults.value;
const operator = getOperatorByName(req.params.func);
if(operator) {

View File

@ -6,6 +6,7 @@ const upload = multer();
import { traverseOperations } from "@stirling-pdf/shared-operations/src/workflow/traverseOperations";
import { PdfFile, RepresentationType } from '@stirling-pdf/shared-operations/src/wrappers/PdfFile';
import { respondWithPdfFiles } from '../../utils/endpoint-utils';
import { JoiPDFFileSchema } from '@stirling-pdf/shared-operations/src/wrappers/PdfFileJoi';
interface Workflow {
eventStream?: express.Response<any, Record<string, any>>,
@ -42,7 +43,12 @@ router.post("/:workflowUuid?", [
}
}
const inputs = PdfFile.fromMulterFiles(req.files as Express.Multer.File[]);
const validationResults = JoiPDFFileSchema.validate(req.files);
if(validationResults.error) {
res.status(400).json({error: "PDF validation failed", details: validationResults.error.message});
return;
}
const inputs: PdfFile[] = validationResults.value;
// Allow option to do it synchronously and just make a long request
if(req.body.async === "false") {

View File

@ -1,22 +1,27 @@
import Joi from "joi";
import { PdfFile } from "./PdfFile";
export const JoiPDFFileSchema = Joi.binary().custom((value: Express.Multer.File[] | PdfFile | PdfFile[], helpers) => {
if (value instanceof PdfFile) {
return value;
}
else if (Array.isArray(value)) {
if(value.every((e) => e instanceof PdfFile))
export const JoiPDFFileSchema = Joi.custom((value: Express.Multer.File | Express.Multer.File[] | PdfFile | PdfFile[], helpers) => {
if (Array.isArray(value)) {
if(isPdfFileArray(value))
return value;
else
throw new Error("Some elements in the array are not of type PdfFile");
}
else {
try {
else { // File(s)
if(value.some(f => f.mimetype != "application/pdf"))
throw new Error("at least one of the files provided doesn't seem to be a PDF.");
return PdfFile.fromMulterFiles(value);
} catch (error) {
console.error(error);
throw new Error('value is not of type PdfFile');
}
}
}, "pdffile validation");
else {
if (value instanceof PdfFile) {
return value;
}
else {
throw new Error("an invalid type (unhandeled, non-file-type) was provided to pdf validation process. Please report this to maintainers.");
}
}
}, "pdffile validation");
function isPdfFileArray(value: any): value is PdfFile[] {
return value.every((e) => e instanceof PdfFile)
}