mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 21:46:49 +00:00
test(files): upload filters fail closed on an excluded or unresolvable type
This commit is contained in:
@@ -56,14 +56,21 @@ export function filesUploadFileFilter(allowedTypes: AllowedFileTypesService): Op
|
||||
// allowed-extension list is now an async read. The decision runs in a
|
||||
// detached async function that always answers through `cb` — multer holds
|
||||
// the file stream until it does (make-middleware.js says as much). A
|
||||
// rejection refuses the file, so the filter still fails closed.
|
||||
// rejection refuses the file, so the filter still fails closed. Only the
|
||||
// await is wrapped in try/catch, so a throw from cb() itself is never
|
||||
// re-routed into a second cb() call.
|
||||
void (async () => {
|
||||
const allowed = (await allowedTypes.get()).split(',').map((e) => e.trim().toLowerCase());
|
||||
let allowed: string[];
|
||||
try {
|
||||
allowed = (await allowedTypes.get()).split(',').map((e) => e.trim().toLowerCase());
|
||||
} catch {
|
||||
return reject();
|
||||
}
|
||||
const fileExt = ext.replace('.', '');
|
||||
// Video is accepted as media regardless of the admin doc-types allowlist (#823).
|
||||
if (allowed.includes(fileExt) || isVideoExtension(fileExt) || (allowed.includes('*') && !BLOCKED_EXTENSIONS.includes(ext))) return cb(null, true);
|
||||
reject();
|
||||
})().catch(() => reject());
|
||||
})();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -78,23 +78,27 @@ export function journeyImageFileFilter(allowedTypes: AllowedFileTypesService): O
|
||||
return cb(err);
|
||||
}
|
||||
const ext = path.extname(file.originalname).toLowerCase().replace('.', '');
|
||||
// R1.5: multer's fileFilter is a callback API that cannot await, and the
|
||||
// allowed-extension list is now an async read. The decision runs in a
|
||||
// detached async function that always answers through `cb`; a rejection
|
||||
// refuses the file, so the filter still fails closed.
|
||||
void (async () => {
|
||||
const allowed = (await allowedTypes.get()).split(',').map((e) => e.trim().toLowerCase());
|
||||
if (!allowed.includes('*') && !allowed.includes(ext)) {
|
||||
const err: Error & { statusCode?: number } = new Error(`File type .${ext} is not allowed`);
|
||||
err.statusCode = 400;
|
||||
return cb(err);
|
||||
}
|
||||
cb(null, true);
|
||||
})().catch(() => {
|
||||
const reject = () => {
|
||||
const err: Error & { statusCode?: number } = new Error(`File type .${ext} is not allowed`);
|
||||
err.statusCode = 400;
|
||||
cb(err);
|
||||
});
|
||||
};
|
||||
// R1.5: multer's fileFilter is a callback API that cannot await, and the
|
||||
// allowed-extension list is now an async read. The decision runs in a
|
||||
// detached async function that always answers through `cb`; a rejection
|
||||
// refuses the file, so the filter still fails closed. Only the await is
|
||||
// wrapped in try/catch, so a throw from cb() itself is never re-routed
|
||||
// into a second cb() call.
|
||||
void (async () => {
|
||||
let allowed: string[];
|
||||
try {
|
||||
allowed = (await allowedTypes.get()).split(',').map((e) => e.trim().toLowerCase());
|
||||
} catch {
|
||||
return reject();
|
||||
}
|
||||
if (!allowed.includes('*') && !allowed.includes(ext)) return reject();
|
||||
cb(null, true);
|
||||
})();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user