From d7ffb8aa52653106a68b85bd3d5ad0cc2efd553d Mon Sep 17 00:00:00 2001 From: Ivo Oskamp Date: Thu, 8 Jan 2026 13:47:59 +0100 Subject: [PATCH] Auto-commit local changes before build (2026-01-08 13:47:59) --- .last-branch | 2 +- .../src/backend/app/mail_importer.py | 12 +++++++--- .../src/backend/app/main/routes_inbox.py | 23 +++++++++++++++---- .../src/templates/main/inbox.html | 8 +++++++ docs/changelog.md | 14 ++++++++--- 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/.last-branch b/.last-branch index 53c4b67..913d3b2 100644 --- a/.last-branch +++ b/.last-branch @@ -1 +1 @@ -v20260108-28-admin-all-mail-open-fix +v20260108-29-inbox-attachment-body-fallback diff --git a/containers/backupchecks/src/backend/app/mail_importer.py b/containers/backupchecks/src/backend/app/mail_importer.py index 7d6f397..d4a4dae 100644 --- a/containers/backupchecks/src/backend/app/mail_importer.py +++ b/containers/backupchecks/src/backend/app/mail_importer.py @@ -228,9 +228,15 @@ def _store_messages(settings: SystemSettings, messages): ) # Some systems send empty bodies and put the actual report in an HTML attachment. - # If we have raw EML bytes and no body content, extract the first HTML attachment - # and use it as the HTML body so parsers and the inbox preview can work. - if not (mail.html_body or mail.text_body) and mail.eml_blob: + # Graph may still return a body that only contains whitespace/newlines; treat that + # as empty so we can fall back to the attachment. + def _is_blank(s): + return s is None or (isinstance(s, str) and s.strip() == "") + + # If we have raw EML bytes and no meaningful body content, extract the first + # HTML attachment and use it as the HTML body so parsers and the inbox preview + # can work. + if _is_blank(mail.html_body) and _is_blank(mail.text_body) and mail.eml_blob: attachment_html = extract_best_html_from_eml(mail.eml_blob) if attachment_html: mail.html_body = attachment_html diff --git a/containers/backupchecks/src/backend/app/main/routes_inbox.py b/containers/backupchecks/src/backend/app/main/routes_inbox.py index 5440c9f..de3bcc8 100644 --- a/containers/backupchecks/src/backend/app/main/routes_inbox.py +++ b/containers/backupchecks/src/backend/app/main/routes_inbox.py @@ -1,6 +1,8 @@ from .routes_shared import * # noqa: F401,F403 from .routes_shared import _format_datetime, _log_admin_event, _send_mail_message_eml_download +from ..email_utils import extract_best_html_from_eml + import time @main_bp.route("/inbox") @@ -111,11 +113,24 @@ def inbox_message_detail(message_id: int): ), } - if getattr(msg, "html_body", None): - body_html = msg.html_body - elif getattr(msg, "text_body", None): + def _is_blank(s): + return s is None or (isinstance(s, str) and s.strip() == "") + + html_body = getattr(msg, "html_body", None) + text_body = getattr(msg, "text_body", None) + + # For legacy messages: if the Graph body is empty/whitespace but the real report + # is an HTML attachment in the stored EML, extract and render it. + if _is_blank(html_body) and _is_blank(text_body) and getattr(msg, "eml_blob", None): + extracted = extract_best_html_from_eml(getattr(msg, "eml_blob", None)) + if extracted: + html_body = extracted + + if not _is_blank(html_body): + body_html = html_body + elif not _is_blank(text_body): escaped = ( - msg.text_body.replace("&", "&") + text_body.replace("&", "&") .replace("<", "<") .replace(">", ">") ) diff --git a/containers/backupchecks/src/templates/main/inbox.html b/containers/backupchecks/src/templates/main/inbox.html index 760c141..30f9cc4 100644 --- a/containers/backupchecks/src/templates/main/inbox.html +++ b/containers/backupchecks/src/templates/main/inbox.html @@ -334,6 +334,14 @@ function wrapMailHtml(html) { html = html || ""; + var trimmed = (typeof html === "string") ? html.trim() : ""; + + // If the content already looks like a full HTML document (common for report attachments), + // do not wrap it again. + if (trimmed.toLowerCase().indexOf("" + diff --git a/docs/changelog.md b/docs/changelog.md index fea8182..137784d 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -16,10 +16,18 @@ --- -## v20260108-28-admin-all-mail-open-fix -- Fixed All Mail row-click handling by switching to event delegation, ensuring message rows reliably open the detail modal. -- Ensured EML link clicks no longer trigger row-click modal opening. +## v20260108-28-admin-all-mail-popup-fix +- Fixed mail popup opening in the Admin All Mail audit page. +- Aligned click and modal handling with the Inbox implementation to ensure messages can be opened correctly. +- No functional changes to search, filtering, pagination, or permissions. + +--- + +## v20260108-29-inbox-attachment-body-fallback +- Treat whitespace-only email bodies as empty during import, so HTML report attachments can be extracted from stored EML and shown as the message body. +- Add legacy fallback in the Inbox message detail API: when stored bodies are empty/whitespace, extract the first HTML attachment from EML and render it. +- Improve Inbox iframe rendering: if the returned content is a full HTML document (common for report attachments), render it directly instead of wrapping it. ================================================================================================================================================ ## v0.1.18 -- 2.45.2