mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-22 23:16:46 +00:00
fix(server): upload filters answer multer once on a throwing callback; positive call-graph gate test
This commit is contained in:
@@ -58,8 +58,8 @@ export function filesUploadFileFilter(allowedTypes: AllowedFileTypesService): Op
|
||||
// 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. Only the
|
||||
// await is wrapped in try/catch, so a throw from cb() itself is never
|
||||
// re-routed into a second cb() call.
|
||||
// await is wrapped in try/catch; a throw from cb() itself lands in the
|
||||
// trailing .catch, which logs it and answers multer one final time.
|
||||
(async () => {
|
||||
let allowed: string[];
|
||||
try {
|
||||
@@ -73,7 +73,14 @@ export function filesUploadFileFilter(allowedTypes: AllowedFileTypesService): Op
|
||||
reject();
|
||||
})().catch((err: unknown) => {
|
||||
logError(`files upload fileFilter: ${err instanceof Error ? err.message : String(err)}`);
|
||||
cb(err instanceof Error ? err : new Error(String(err)));
|
||||
// cb() itself is the only thing that can reach here (every await is
|
||||
// inside the try above); answer once more so multer never hangs, but a
|
||||
// second throw from cb() means multer already answered — swallow it.
|
||||
try {
|
||||
cb(err instanceof Error ? err : new Error(String(err)));
|
||||
} catch {
|
||||
/* multer already answered */
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -88,8 +88,8 @@ export function journeyImageFileFilter(allowedTypes: AllowedFileTypesService): O
|
||||
// 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.
|
||||
// wrapped in try/catch; a throw from cb() itself lands in the trailing
|
||||
// .catch, which logs it and answers multer one final time.
|
||||
(async () => {
|
||||
let allowed: string[];
|
||||
try {
|
||||
@@ -101,7 +101,14 @@ export function journeyImageFileFilter(allowedTypes: AllowedFileTypesService): O
|
||||
cb(null, true);
|
||||
})().catch((err: unknown) => {
|
||||
logError(`journey photo fileFilter: ${err instanceof Error ? err.message : String(err)}`);
|
||||
cb(err instanceof Error ? err : new Error(String(err)));
|
||||
// cb() itself is the only thing that can reach here (every await is
|
||||
// inside the try above); answer once more so multer never hangs, but a
|
||||
// second throw from cb() means multer already answered — swallow it.
|
||||
try {
|
||||
cb(err instanceof Error ? err : new Error(String(err)));
|
||||
} catch {
|
||||
/* multer already answered */
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ export async function getActiveNoticesFor(
|
||||
// `evaluate` runs inside a .filter(), which cannot await, so the addon flags
|
||||
// the registry is able to ask about are resolved up front and handed to it as
|
||||
// a lookup. The ids come from the notices themselves, so every question the
|
||||
// conditions can ask has an answer here and the fallback is unreachable.
|
||||
// conditions can ask has an answer here.
|
||||
const addonFlags = new Map<string, boolean>();
|
||||
for (const condition of SYSTEM_NOTICES.flatMap(n => n.conditions)) {
|
||||
if (condition.kind === 'addonEnabled' && !addonFlags.has(condition.addonId)) {
|
||||
|
||||
Reference in New Issue
Block a user