Add sensitive flag

This commit is contained in:
Raphael Michel
2026-01-29 22:47:11 +01:00
parent 164eac2e3f
commit da8c3711f9
9 changed files with 46 additions and 5 deletions

View File

@@ -32,6 +32,7 @@ class Migration(migrations.Migration):
("retry_after", models.DateTimeField(blank=True, null=True)),
("error", models.TextField(null=True)),
("error_detail", models.TextField(null=True)),
("sensitive", models.BooleanField(default=False)),
("subject", models.TextField()),
("body_plain", models.TextField()),
("body_html", models.TextField(null=True)),
@@ -40,7 +41,7 @@ class Migration(migrations.Migration):
("to", models.JSONField(default=list)),
("cc", models.JSONField(default=list)),
("bcc", models.JSONField(default=list)),
("recipient_count", models.IntegerField(default=1)),
("recipient_count", models.IntegerField()),
("should_attach_tickets", models.BooleanField(default=False)),
("should_attach_ical", models.BooleanField(default=False)),
("should_attach_other_files", models.JSONField(default=list)),

View File

@@ -293,6 +293,7 @@ class Customer(LoggedModel):
locale=self.locale,
customer=self,
organizer=self.organizer,
sensitive=True,
)
def usable_gift_cards(self, used_cards=[]):

View File

@@ -135,6 +135,7 @@ class OutgoingMail(models.Model):
null=True, blank=True,
)
sensitive = models.BooleanField(default=False)
subject = models.TextField()
body_plain = models.TextField()
body_html = models.TextField(null=True)

View File

@@ -152,7 +152,8 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
position: OrderPosition = None, *, headers: dict = None, sender: str = None, organizer: Organizer = None,
customer: Customer = None, invoices: Sequence = None, attach_tickets=False, auto_email=True, user=None,
attach_ical=False, attach_cached_files: Sequence = None, attach_other_files: list=None,
plain_text_only=False, no_order_links=False, cc: Sequence[str]=None, bcc: Sequence[str]=None):
plain_text_only=False, no_order_links=False, cc: Sequence[str]=None, bcc: Sequence[str]=None,
sensitive: bool=False):
"""
Sends out an email to a user. The mail will be sent synchronously or asynchronously depending on the installation.
@@ -208,6 +209,9 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
only allowed to use together with ``plain_text_only`` since HTML renderers add their own
links.
:param sensitive: If set to ``True``, the email content will not be shown as part of log entries, used e.g. for
password resets. Bcc will also not be used.
:raises MailOrderException: on obvious, immediate failures. Not raising an exception does not necessarily mean
that the email has been sent, just that it has been queued by the email backend.
"""
@@ -228,7 +232,7 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
headers.setdefault('X-PX-Correlation', str(guid))
bcc = list(bcc or [])
if settings_holder and settings_holder.settings.mail_bcc:
if settings_holder and settings_holder.settings.mail_bcc and not sensitive:
for bcc_mail in settings_holder.settings.mail_bcc.split(','):
bcc.append(bcc_mail.strip())
@@ -321,6 +325,7 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
should_attach_tickets=attach_tickets,
should_attach_ical=attach_ical,
should_attach_other_files=attach_other_files or [],
sensitive=sensitive,
)
if invoices and not position:
m.should_attach_invoices.add(*invoices)
@@ -721,6 +726,7 @@ def mail_send_task(self, *args, outgoing_mail: int) -> bool:
},
}
)
return True
def mail_send(to: List[str], subject: str, body: str, html: Optional[str], sender: str,

View File

@@ -585,6 +585,7 @@ class MailSettingsForm(SettingsForm):
help_text=''.join([
str(_("All emails will be sent to this address as a Bcc copy.")),
str(_("You can specify multiple recipients separated by commas.")),
str(_("Sensitive emails like password resets will not be sent in Bcc.")),
]),
validators=[multimail_validate],
required=False,

View File

@@ -171,13 +171,39 @@
<div role="tabpanel"
class="tab-pane {% if not mail.is_failed %}active{% endif %}"
id="tab-html">
{{ data_url|json_script:"mail_body_html" }}
{% if mail.sensitive %}
<div class="empty-collection">
<p>
{% icon "eye-slash 4x" %}
</p>
<p>
{% blocktrans trimmed %}
Sensitive content not shown for security reasons
{% endblocktrans %}
</p>
</div>
{% else %}
{{ data_url|json_script:"mail_body_html" }}
{% endif %}
</div>
{% endif %}
<div role="tabpanel"
class="tab-pane {% if not mail.is_failed and not mail.body_html %}active{% endif %}"
id="tab-text">
<pre><code>{{ mail.body_plain }}</code></pre>
{% if mail.sensitive %}
<div class="empty-collection">
<p>
{% icon "eye-slash 4x" %}
</p>
<p>
{% blocktrans trimmed %}
Sensitive content not shown for security reasons
{% endblocktrans %}
</p>
</div>
{% else %}
<pre><code>{{ mail.body_plain }}</code></pre>
{% endif %}
</div>
<div role="tabpanel"
class="tab-pane"

View File

@@ -96,6 +96,9 @@
<a href="{% url "control:organizer.outgoingmail" organizer=request.organizer.slug mail=m.id %}">
{{ m.subject }}
</a>
{% if m.sensitive %}
<span class="text-muted">{% icon "eye-slash" %}</span>
{% endif %}
</td>
<td>
{{ m.to|join:", " }}

View File

@@ -3011,6 +3011,7 @@ class CustomerDetailView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMi
locale=self.customer.locale,
customer=self.customer,
organizer=self.request.organizer,
sensitive=True,
)
messages.success(
self.request,

View File

@@ -325,6 +325,7 @@ class ResetPasswordView(FormView):
locale=customer.locale,
customer=customer,
organizer=self.request.organizer,
sensitive=True,
)
messages.success(
self.request,