feat: add mimeTypes validation for uploads
This commit is contained in:
committed by
Elliot DeNolf
parent
1c6f32f288
commit
a5fcdf03ba
@@ -10,6 +10,7 @@ import baseUploadFields from '../../fields/baseFields/baseUploadFields';
|
||||
import baseImageUploadFields from '../../fields/baseFields/baseImageUploadFields';
|
||||
import { formatLabels } from '../../utilities/formatLabels';
|
||||
import { defaults, authDefaults } from './defaults';
|
||||
import { mimeTypeValidator } from '../../fields/baseFields/mimeTypeValidator';
|
||||
|
||||
const mergeBaseFields = (fields, baseFields) => {
|
||||
const mergedFields = [];
|
||||
@@ -73,6 +74,10 @@ const sanitizeCollection = (collections: PayloadCollectionConfig[], collection:
|
||||
|
||||
let uploadFields = baseUploadFields;
|
||||
|
||||
if (sanitized.upload.mimeTypes) {
|
||||
uploadFields.find((f) => f.name === 'mimeType').validate = mimeTypeValidator(sanitized.upload.mimeTypes);
|
||||
}
|
||||
|
||||
if (sanitized.upload.imageSizes && Array.isArray(sanitized.upload.imageSizes)) {
|
||||
uploadFields = uploadFields.concat(baseImageUploadFields(sanitized.upload.imageSizes));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import APIError from './APIError';
|
||||
|
||||
class ValidationError extends APIError {
|
||||
constructor(results: {message: string, field: string}[]) {
|
||||
super(`Bad request with ${results.length} errors`, httpStatus.BAD_REQUEST, results);
|
||||
super(`The following field${results.length === 1 ? ' is' : 's are'} invalid: ${results.map((f) => f.field).join(', ')}`, httpStatus.BAD_REQUEST, results);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
55
src/fields/baseFields/mimeTypeValidator.spec.ts
Normal file
55
src/fields/baseFields/mimeTypeValidator.spec.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { mimeTypeValidator } from './mimeTypeValidator';
|
||||
|
||||
describe('mimeTypeValidator', () => {
|
||||
it('should validate single mimeType', () => {
|
||||
const mimeTypes = ['image/png'];
|
||||
const validate = mimeTypeValidator(mimeTypes);
|
||||
expect(validate('image/png')).toBe(true);
|
||||
});
|
||||
|
||||
it('should validate multiple mimeTypes', () => {
|
||||
const mimeTypes = ['image/png', 'application/pdf'];
|
||||
const validate = mimeTypeValidator(mimeTypes);
|
||||
expect(validate('image/png')).toBe(true);
|
||||
expect(validate('application/pdf')).toBe(true);
|
||||
});
|
||||
|
||||
it('should validate using wildcard', () => {
|
||||
const mimeTypes = ['image/*'];
|
||||
const validate = mimeTypeValidator(mimeTypes);
|
||||
expect(validate('image/png')).toBe(true);
|
||||
expect(validate('image/gif')).toBe(true);
|
||||
});
|
||||
|
||||
it('should validate multiple wildcards', () => {
|
||||
const mimeTypes = ['image/*', 'audio/*'];
|
||||
const validate = mimeTypeValidator(mimeTypes);
|
||||
expect(validate('image/png')).toBe(true);
|
||||
expect(validate('audio/mpeg')).toBe(true);
|
||||
});
|
||||
|
||||
it('should not validate when unmatched', () => {
|
||||
const mimeTypes = ['image/png'];
|
||||
const validate = mimeTypeValidator(mimeTypes);
|
||||
expect(validate('audio/mpeg')).toBe('Invalid file type: \'audio/mpeg\'');
|
||||
});
|
||||
|
||||
it('should not validate when unmatched - multiple mimeTypes', () => {
|
||||
const mimeTypes = ['image/png', 'application/pdf'];
|
||||
const validate = mimeTypeValidator(mimeTypes);
|
||||
expect(validate('audio/mpeg')).toBe('Invalid file type: \'audio/mpeg\'');
|
||||
});
|
||||
|
||||
it('should not validate using wildcard - unmatched', () => {
|
||||
const mimeTypes = ['image/*'];
|
||||
const validate = mimeTypeValidator(mimeTypes);
|
||||
expect(validate('audio/mpeg')).toBe('Invalid file type: \'audio/mpeg\'');
|
||||
});
|
||||
|
||||
it('should not validate multiple wildcards - unmatched', () => {
|
||||
const mimeTypes = ['image/*', 'audio/*'];
|
||||
const validate = mimeTypeValidator(mimeTypes);
|
||||
expect(validate('video/mp4')).toBe('Invalid file type: \'video/mp4\'');
|
||||
expect(validate('application/pdf')).toBe('Invalid file type: \'application/pdf\'');
|
||||
});
|
||||
});
|
||||
9
src/fields/baseFields/mimeTypeValidator.ts
Normal file
9
src/fields/baseFields/mimeTypeValidator.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Validate } from '../config/types';
|
||||
|
||||
export const mimeTypeValidator = (mimeTypes: string[]): Validate => (val: string) => {
|
||||
const cleanedMimeTypes = mimeTypes.map((v) => v.replace('*', ''));
|
||||
|
||||
return !cleanedMimeTypes.some((v) => val.startsWith(v))
|
||||
? `Invalid file type: '${val}'`
|
||||
: true;
|
||||
};
|
||||
@@ -40,7 +40,7 @@ export type Labels = {
|
||||
plural: string;
|
||||
};
|
||||
|
||||
export type Validate = (value: unknown, options?: any) => string | boolean | Promise<string | boolean>;
|
||||
export type Validate = (value: unknown, options?: any) => string | true | Promise<string | true>;
|
||||
|
||||
export type OptionObject = {
|
||||
label: string
|
||||
|
||||
Reference in New Issue
Block a user