Anlagen: user_id aus req.user statt AsyncLocalStorage im multer-Callback
In multer/busboy-Upload-Callbacks ist der per-request AsyncLocalStorage- Kontext nicht zuverlässig propagiert, sodass currentUserId() dort null liefern kann und basis_anhaenge-/interne_anhaenge-Zeilen mit user_id=NULL verwaisten (für den User unsichtbar). Die INSERTs nutzen jetzt uidFromReq (= req.user.id mit uid()-Fallback) wie bereits userStorageDirForReq für Signatur/Foto. Zwei bestehende verwaiste Zeilen wurden repariert. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1639,6 +1639,15 @@ initializeDatabase().then(async () => {
|
||||
// to be present inside any protected route or background-per-user task.
|
||||
const uid = () => currentUserId();
|
||||
|
||||
// Inside a multer upload callback the per-request AsyncLocalStorage context
|
||||
// (which uid() reads) is not reliably propagated — busboy drives the multipart
|
||||
// stream from outside the userContext.run(...) scope, so currentUserId() can
|
||||
// come back null there. The request object, by contrast, always carries the
|
||||
// resolved user (set by the auth middleware before the route). Use this for
|
||||
// any INSERT done from within an uploadX(req, res, cb) callback, so the row is
|
||||
// not orphaned with user_id = NULL. Mirrors userStorageDirForReq's reasoning.
|
||||
const uidFromReq = (req) => (req && req.user && req.user.id) || currentUserId();
|
||||
|
||||
// Resolve a per-user storage directory (data/<base>/<userId>/), creating it
|
||||
// on first use. Used for every attachment / signature / photo path so users'
|
||||
// files are isolated on disk the same way their DB rows are.
|
||||
@@ -3206,7 +3215,7 @@ initializeDatabase().then(async () => {
|
||||
: sanitizeInput(original.replace(/\.[^.]+$/, ''));
|
||||
await dbRun(
|
||||
'INSERT INTO basis_anhaenge (user_id, name, dateiname, mime, pfad) VALUES (?, ?, ?, ?, ?)',
|
||||
[uid(), name, sanitizeInput(original), req.file.mimetype || 'application/octet-stream', req.file.filename]
|
||||
[uidFromReq(req), name, sanitizeInput(original), req.file.mimetype || 'application/octet-stream', req.file.filename]
|
||||
);
|
||||
}
|
||||
res.redirect('/vorlagen');
|
||||
@@ -3262,8 +3271,10 @@ initializeDatabase().then(async () => {
|
||||
try {
|
||||
if (err) console.error('Signature upload error:', err.message);
|
||||
if (req.file) {
|
||||
// keep only the newly uploaded file (in the user's subdir)
|
||||
const dir = userStorageDir(signaturDir);
|
||||
// keep only the newly uploaded file (in the user's subdir). Resolve the
|
||||
// dir from req.user (not currentUserId()) — this runs in the multer
|
||||
// callback where the AsyncLocalStorage user context can be absent.
|
||||
const dir = userStorageDirForReq(signaturDir, req);
|
||||
fs.readdirSync(dir).forEach((f) => {
|
||||
if (f !== req.file.filename) fs.promises.unlink(path.join(dir, f)).catch(() => {});
|
||||
});
|
||||
@@ -3300,8 +3311,9 @@ initializeDatabase().then(async () => {
|
||||
try {
|
||||
if (err) console.error('Photo upload error:', err.message);
|
||||
if (req.file) {
|
||||
// keep only the newly uploaded file (in the user's subdir)
|
||||
const dir = userStorageDir(fotoDir);
|
||||
// keep only the newly uploaded file (in the user's subdir). Resolve the
|
||||
// dir from req.user — see /unterschrift handler for why (multer callback).
|
||||
const dir = userStorageDirForReq(fotoDir, req);
|
||||
fs.readdirSync(dir).forEach((f) => {
|
||||
if (f !== req.file.filename) fs.promises.unlink(path.join(dir, f)).catch(() => {});
|
||||
});
|
||||
@@ -3374,7 +3386,7 @@ initializeDatabase().then(async () => {
|
||||
: sanitizeInput(original.replace(/\.[^.]+$/, ''));
|
||||
await dbRun(
|
||||
'INSERT INTO interne_anhaenge (user_id, bewerbung_id, name, dateiname, mime, pfad) VALUES (?, ?, ?, ?, ?, ?)',
|
||||
[uid(), id, name, sanitizeInput(original), req.file.mimetype || 'application/octet-stream', req.file.filename]
|
||||
[uidFromReq(req), id, name, sanitizeInput(original), req.file.mimetype || 'application/octet-stream', req.file.filename]
|
||||
);
|
||||
}
|
||||
res.redirect('/bewerbung/' + id);
|
||||
|
||||
Reference in New Issue
Block a user