Spam-Anhänge: klarer Fehler statt Junk-Ordner-Raterei (Pentest R124)

Nachtrag zum R124-Fix: statt bei nicht auffindbarem Junk-Ordner still
auf INBOX bzw. den geratenen String 'Junk' zurückzufallen, wird jetzt
ein klarer Fehler zurückgegeben – sonst könnte im Randfall (Junk-Ordner
serverseitig entfernt/umbenannt) doch wieder die falsche UID aus dem
falschen Ordner gezogen werden.

- 4 Controller-Funktionen (downloadAttachment, saveAttachmentTo,
  saveAttachmentAsInvoice, saveAttachmentAsContractDocument):
  404 "Postfach hat keinen Spam-/Junk-Ordner (mehr)".
- 2 Service-Funktionen (moveEmailToTrash, restoreEmailFromTrash):
  klare error-Message im TrashOperationResult.

Kein undefined mehr Richtung IMAP-Lib.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-07-27 16:30:49 +02:00
co-authored by Claude Opus 4.7
parent 0a0cbe0e53
commit 627cae9b3b
3 changed files with 64 additions and 6 deletions
@@ -749,7 +749,18 @@ export async function downloadAttachment(req: AuthRequest, res: Response): Promi
if (email.folder === 'SENT') {
imapFolder = 'Sent';
} else if (email.folder === 'SPAM') {
imapFolder = (await findJunkFolderPath(credentials)) || 'Junk';
// Kein stiller Fallback: findet sich der Junk-Ordner nicht (mehr),
// lieber ein klarer Fehler als aus dem falschen Ordner (INBOX/'Junk')
// die falsche UID zu ziehen.
const junkPath = await findJunkFolderPath(credentials);
if (!junkPath) {
res.status(404).json({
success: false,
error: 'Postfach hat keinen Spam-/Junk-Ordner (mehr) Anhang nicht abrufbar',
} as ApiResponse);
return;
}
imapFolder = junkPath;
} else {
imapFolder = 'INBOX';
}
@@ -1426,7 +1437,18 @@ export async function saveAttachmentTo(req: AuthRequest, res: Response): Promise
if (email.folder === 'SENT') {
imapFolder = 'Sent';
} else if (email.folder === 'SPAM') {
imapFolder = (await findJunkFolderPath(credentials)) || 'Junk';
// Kein stiller Fallback: findet sich der Junk-Ordner nicht (mehr),
// lieber ein klarer Fehler als aus dem falschen Ordner (INBOX/'Junk')
// die falsche UID zu ziehen.
const junkPath = await findJunkFolderPath(credentials);
if (!junkPath) {
res.status(404).json({
success: false,
error: 'Postfach hat keinen Spam-/Junk-Ordner (mehr) Anhang nicht abrufbar',
} as ApiResponse);
return;
}
imapFolder = junkPath;
} else {
imapFolder = 'INBOX';
}
@@ -2244,7 +2266,18 @@ export async function saveAttachmentAsInvoice(req: AuthRequest, res: Response):
if (email.folder === 'SENT') {
imapFolder = 'Sent';
} else if (email.folder === 'SPAM') {
imapFolder = (await findJunkFolderPath(credentials)) || 'Junk';
// Kein stiller Fallback: findet sich der Junk-Ordner nicht (mehr),
// lieber ein klarer Fehler als aus dem falschen Ordner (INBOX/'Junk')
// die falsche UID zu ziehen.
const junkPath = await findJunkFolderPath(credentials);
if (!junkPath) {
res.status(404).json({
success: false,
error: 'Postfach hat keinen Spam-/Junk-Ordner (mehr) Anhang nicht abrufbar',
} as ApiResponse);
return;
}
imapFolder = junkPath;
} else {
imapFolder = 'INBOX';
}
@@ -2415,7 +2448,18 @@ export async function saveAttachmentAsContractDocument(req: AuthRequest, res: Re
if (email.folder === 'SENT') {
imapFolder = 'Sent';
} else if (email.folder === 'SPAM') {
imapFolder = (await findJunkFolderPath(credentials)) || 'Junk';
// Kein stiller Fallback: findet sich der Junk-Ordner nicht (mehr),
// lieber ein klarer Fehler als aus dem falschen Ordner (INBOX/'Junk')
// die falsche UID zu ziehen.
const junkPath = await findJunkFolderPath(credentials);
if (!junkPath) {
res.status(404).json({
success: false,
error: 'Postfach hat keinen Spam-/Junk-Ordner (mehr) Anhang nicht abrufbar',
} as ApiResponse);
return;
}
imapFolder = junkPath;
} else {
imapFolder = 'INBOX';
}
+10 -2
View File
@@ -824,7 +824,11 @@ export async function moveEmailToTrash(id: number): Promise<TrashOperationResult
if (email.folder === 'SENT') {
sourceFolder = 'Sent';
} else if (email.folder === 'SPAM') {
sourceFolder = (await findJunkFolderPath(credentials)) || 'Junk';
const junkPath = await findJunkFolderPath(credentials);
if (!junkPath) {
return { success: false, error: 'Spam-/Junk-Ordner nicht gefunden kann nicht in den Papierkorb verschieben' };
}
sourceFolder = junkPath;
} else {
sourceFolder = 'INBOX';
}
@@ -899,7 +903,11 @@ export async function restoreEmailFromTrash(id: number): Promise<TrashOperationR
if (email.folder === 'SENT') {
targetFolder = 'Sent';
} else if (email.folder === 'SPAM') {
targetFolder = (await findJunkFolderPath(credentials)) || 'Junk';
const junkPath = await findJunkFolderPath(credentials);
if (!junkPath) {
return { success: false, error: 'Spam-/Junk-Ordner nicht gefunden kann nicht wiederherstellen' };
}
targetFolder = junkPath;
} else {
targetFolder = 'INBOX';
}
+6
View File
@@ -111,6 +111,12 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
Datenintegritätsproblem.
- Fix: an allen vier Stellen dieselbe Junk-Pfad-Logik wie in
`moveEmailToTrash` + `findJunkFolderPath` importiert.
- Randfall (Pentester-Nachtrag): findet sich der Junk-Ordner nicht
(mehr), wird jetzt ein klarer Fehler zurückgegeben statt still auf
INBOX/`'Junk'` zu raten in allen 4 Controller-Funktionen (404
„Anhang nicht abrufbar") und den 2 Service-Funktionen
(`moveEmailToTrash`/`restoreEmailFromTrash`). Kein `undefined` mehr
Richtung IMAP-Lib.
- [x] **📧 E-Mail-Client: Spam-Ordner als eigener Tab**
- Neuer Tab „Spam" (zwischen Gesendet und Papierkorb) im E-Mail-Client,