{{ subject }}

{% for m in messages %}
{{ m.from_name or m.from_addr }} <{{ m.from_addr }}> {# `m.labels` is display text, not raw IMAP keywords: routes_mail.py resolves each keyword to its label's name (or, for a keyword with no matching label row, decodes it back from the hex-escape encoding if it is one of ours, or shows it verbatim if it is not -- see `cove/labels.py::display_names_for_keywords`). Jinja's `join` filter escapes each element under autoescape (verified directly), so a label name containing markup (see test_create_label_markup_name_is_ data_not_html) still can't inject here. #} {% if m.labels %}{{ m.labels | join(", ") }}{% endif %}
{% if m.blocked_remote %}

{{ m.blocked_remote }} remote image(s) blocked. Show images

{% endif %} {# `sandbox=""` is load-bearing: no allow-scripts, no allow-same-origin. Do not add either. When the HTML cannot be rendered safely we do not point an iframe at it at all -- we show the plain-text part, which needs no sanitizer to be safe, and only fall through to a notice when the message genuinely has no readable text. #} {% if m.html_renderable %} {% elif m.visible or m.quoted %}
{{ m.visible }}
{% else %}

This message is too large or complex to render safely.

{% endif %} {% if m.quoted %}
…
{{ m.quoted }}
{% endif %} {% for att in m.attachments %}

{{ att.filename }} {{ att.size }} bytes

{% endfor %}
{% endfor %}