diff --git a/src/pretix/api/serializers/organizer.py b/src/pretix/api/serializers/organizer.py index 754dc2d65..9df859701 100644 --- a/src/pretix/api/serializers/organizer.py +++ b/src/pretix/api/serializers/organizer.py @@ -27,7 +27,7 @@ from django.core.exceptions import ObjectDoesNotExist from django.db import transaction from django.db.models import Q from django.utils.crypto import get_random_string -from django.utils.translation import gettext_lazy as _ +from django.utils.translation import gettext, gettext_lazy as _ from rest_framework import serializers from rest_framework.exceptions import ValidationError @@ -492,7 +492,9 @@ class TeamInviteSerializer(serializers.ModelSerializer): def _send_invite(self, instance): mail( instance.email, - _('Account invitation'), + gettext('You\'ve been invited to join %(organizer)s') % { + 'organizer': self.context['organizer'].name, + }, 'pretixcontrol/email/invitation.txt', { 'instance': settings.PRETIX_INSTANCE_NAME, diff --git a/src/pretix/base/models/auth.py b/src/pretix/base/models/auth.py index f8295877a..540ffbc66 100644 --- a/src/pretix/base/models/auth.py +++ b/src/pretix/base/models/auth.py @@ -373,7 +373,7 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin): mail( email or self.email, - _('Account information changed'), + _('Changes to your account'), 'pretixcontrol/email/security_notice.txt', { 'user': self, @@ -400,12 +400,13 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin): with language(self.locale): if reason == 'email_change': - msg = str(_('to confirm changing your email address from {old_email}\nto {new_email}, use the following code:').format( + msg = str(_('To change your email address from {old_email} to {new_email}, use the following code:').format( old_email=self.email, new_email=email, )) elif reason == 'email_verify': - msg = str(_('to confirm that your email address {email} belongs to your pretix account, use the following code:').format( + msg = str(_('To verify your email address {email} on {instance}, use the following code:').format( email=self.email, + instance=settings.PRETIX_INSTANCE_NAME, )) else: raise Exception('Invalid confirmation code reason') @@ -418,7 +419,7 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin): } mail( email or self.email, - _('pretix confirmation code'), + _('Your confirmation code'), 'pretixcontrol/email/confirmation_code.txt', { 'user': self, @@ -462,7 +463,9 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin): from pretix.base.services.mail import mail mail( - self.email, _('Password recovery'), 'pretixcontrol/email/forgot.txt', + self.email, + _('Reset your password'), + 'pretixcontrol/email/forgot.txt', { 'instance': settings.PRETIX_INSTANCE_NAME, 'user': self, diff --git a/src/pretix/base/services/cancelevent.py b/src/pretix/base/services/cancelevent.py index 575a13f14..130aae2df 100644 --- a/src/pretix/base/services/cancelevent.py +++ b/src/pretix/base/services/cancelevent.py @@ -22,6 +22,7 @@ import logging from decimal import Decimal +from django.conf import settings from django.db import transaction from django.db.models import Count, Exists, IntegerField, OuterRef, Q, Subquery from django.utils.crypto import get_random_string @@ -377,12 +378,13 @@ def cancel_event(self, event: Event, subevent: int, auto_refund: bool, confirmation_code = get_random_string(8, allowed_chars="01234567890") mail( user.email, - subject=gettext('Bulk-refund confirmation'), + subject=gettext('Confirm event cancellation and bulk refund'), template='pretixbase/email/cancel_confirm.txt', context={ "event": str(event), "amount": money_filter(refund_total, event.currency), "confirmation_code": confirmation_code, + "instance": settings.PRETIX_INSTANCE_NAME, }, locale=user.locale, ) diff --git a/src/pretix/base/services/export.py b/src/pretix/base/services/export.py index 93d214497..5c67effe2 100644 --- a/src/pretix/base/services/export.py +++ b/src/pretix/base/services/export.py @@ -340,12 +340,13 @@ def _run_scheduled_export(schedule, context: Union[Event, Organizer], exporter, if schedule.owner.is_active: mail( email=schedule.owner.email, - subject=gettext('Export failed'), + subject=gettext('Scheduled export failed'), template='pretixbase/email/export_failed.txt', context={ 'configuration_url': config_url, 'reason': msg, 'soft': soft, + 'instance': settings.PRETIX_INSTANCE_NAME, }, event=context if isinstance(context, Event) else None, organizer=context.organizer if isinstance(context, Event) else context, diff --git a/src/pretix/base/services/shredder.py b/src/pretix/base/services/shredder.py index 43d88b362..6e2b68763 100644 --- a/src/pretix/base/services/shredder.py +++ b/src/pretix/base/services/shredder.py @@ -44,7 +44,7 @@ from django.conf import settings from django.utils.crypto import get_random_string from django.utils.formats import date_format from django.utils.timezone import now -from django.utils.translation import gettext_lazy as _ +from django.utils.translation import gettext, gettext_lazy as _ from pretix.base.i18n import language from pretix.base.models import CachedFile, Event, User, cachedfile_name @@ -171,15 +171,16 @@ def shred(self, event: Event, fileid: str, confirm_code: str, user: int=None, lo if user: with language(user.locale): + event_name = str(event.name) mail( user.email, - _('Data shredding completed'), + gettext('Data shredding completed for %(event)s') % {'event': event_name}, 'pretixbase/email/shred_completed.txt', { 'instance': settings.PRETIX_INSTANCE_NAME, 'user': user, 'organizer': event.organizer.name, - 'event': str(event.name), + 'event': event_name, 'start_time': date_format(parse(indexdata['time']).astimezone(event.timezone), 'SHORT_DATETIME_FORMAT'), 'shredders': ', '.join([str(s.verbose_name) for s in shredders]) }, diff --git a/src/pretix/base/templates/pretixbase/email/cancel_confirm.txt b/src/pretix/base/templates/pretixbase/email/cancel_confirm.txt index 5e3043156..c9da3aa6d 100644 --- a/src/pretix/base/templates/pretixbase/email/cancel_confirm.txt +++ b/src/pretix/base/templates/pretixbase/email/cancel_confirm.txt @@ -1,10 +1,14 @@ {% load i18n %} -{% trans "You have requested us to cancel an event which includes a larger bulk-refund:" %} +{% trans "You requested to cancel an event that involves a large bulk refund:" %} -{% trans "Event" %}: {{ event }} +- {% trans "Event" %}: {{ event }} +- {% trans "Estimated refund" %}: **{{ amount }}** -{% trans "Estimated refund amount" %}: **{{ amount }}** +{% trans "To confirm, paste the following code into the cancellation form:" %} -{% trans "Please confirm that you want to proceed by coping the following confirmation code into the cancellation form:" %} + {{ confirmation_code }} -**{{ confirmation_code }}** +{% blocktrans with instance=instance %}Don't share this code with anyone. The {{ instance }} team will never ask you for it.{% endblocktrans %} + +{% blocktrans with instance=instance %}Thanks, +The {{ instance }} Team{% endblocktrans %} diff --git a/src/pretix/base/templates/pretixbase/email/export_failed.txt b/src/pretix/base/templates/pretixbase/email/export_failed.txt index f11d8e2c2..d3dc36070 100644 --- a/src/pretix/base/templates/pretixbase/email/export_failed.txt +++ b/src/pretix/base/templates/pretixbase/email/export_failed.txt @@ -1,12 +1,13 @@ {% load i18n %} -{% trans "Your export failed." %} +{% trans "Your scheduled export failed." %} -{% trans "Reason:" %} {{ reason }} +- {% trans "Reason" %}: {{ reason }} -{% if not soft %} -{% trans "If your export fails five times in a row, it will no longer be sent." %} -{% endif %} +{% if not soft %}{% trans "If an export fails five times in a row, we'll stop sending it." %}{% endif %} -{% trans "Configuration link:" %} +{% trans "You can adjust or remove this export here:" %} {{ configuration_url }} + +{% blocktrans with instance=instance %}Thanks, +The {{ instance }} Team{% endblocktrans %} diff --git a/src/pretix/base/templates/pretixbase/email/notification.html b/src/pretix/base/templates/pretixbase/email/notification.html index 76b70c2dd..81b673d8f 100644 --- a/src/pretix/base/templates/pretixbase/email/notification.html +++ b/src/pretix/base/templates/pretixbase/email/notification.html @@ -52,13 +52,13 @@
|
- {% trans "You receive these emails based on your notification settings." %}
diff --git a/src/pretix/base/templates/pretixbase/email/notification.txt b/src/pretix/base/templates/pretixbase/email/notification.txt
index b4174b250..8e5614542 100644
--- a/src/pretix/base/templates/pretixbase/email/notification.txt
+++ b/src/pretix/base/templates/pretixbase/email/notification.txt
@@ -1,19 +1,21 @@
{% load i18n %}
{{ notification.title }}{% if notification.detail %}
-{{ notification.detail }}
-{% endif %}{% if notification.url %}
+{{ notification.detail }}{% endif %}{% if notification.url %}
-{{ notification.url }}{% endif %}{% for attr in notification.attributes %}
+{{ notification.url }}{% endif %}{% if notification.attributes %}
-{{ attr.title }}: {{ attr.value }}{% endfor %}{% for action in notification.actions %}
+{% for attr in notification.attributes %}- {{ attr.title }}: {{ attr.value }}
+{% endfor %}{% endif %}{% for action in notification.actions %}
-{{ action.label }}
- {{ action.url }}{% endfor %}
+{{ action.label }}:
-{% trans "You receive these emails based on your notification settings." %}
-{% trans "Click here to view and change your notification settings:" %}
-{{ settings_url }}
-{% if disable_url %}{% trans "Click here disable all notifications immediately:" %}
-{{ disable_url }}
+{{ action.url }}{% endfor %}
+
+---
+
+{% trans "You're receiving this email based on your notification settings." %}
+
+- {% trans "Manage settings" %}: {{ settings_url }}
+{% if disable_url %}- {% trans "Disable all notifications" %}: {{ disable_url }}
{% endif %}
diff --git a/src/pretix/base/templates/pretixbase/email/shred_completed.txt b/src/pretix/base/templates/pretixbase/email/shred_completed.txt
index 4bde98e16..49e375c92 100644
--- a/src/pretix/base/templates/pretixbase/email/shred_completed.txt
+++ b/src/pretix/base/templates/pretixbase/email/shred_completed.txt
@@ -1,17 +1,14 @@
-{% load i18n %}
-{% load i18n %}{% blocktrans with url=url|safe %}Hello,
+{% load i18n %}{% blocktrans %}Hello,
-we hereby confirm that the following data shredding job has been completed:
+The following data shredding job has been completed:
-Organizer: {{ organizer }}
+- Organizer: {{ organizer }}
+- Event: {{ event }}
+- Data selection: {{ shredders }}
+- Start time: {{ start_time }}
-Event: {{ event }}
+Any data added to the event after the start time may not have been deleted.
-Data selection: {{ shredders }}
-
-Start time: {{ start_time }} (new data added after this time might not have been deleted)
-
-Best regards,
-
-Your {{ instance }} team
+Thanks,
+The {{ instance }} Team
{% endblocktrans %}
diff --git a/src/pretix/control/templates/pretixcontrol/email/confirmation_code.txt b/src/pretix/control/templates/pretixcontrol/email/confirmation_code.txt
index 27966e6d9..38fc7c5da 100644
--- a/src/pretix/control/templates/pretixcontrol/email/confirmation_code.txt
+++ b/src/pretix/control/templates/pretixcontrol/email/confirmation_code.txt
@@ -1,13 +1,13 @@
-{% load i18n %}{% blocktrans with url=url|safe messages=messages|safe %}Hello,
+{% load i18n %}{% blocktrans with code=code reason=reason instance=instance %}Hello,
{{ reason }}
{{ code }}
-Please do never give this code to another person. Our support team will never ask for this code.
+Don't share this code with anyone. The {{ instance }} team will never ask you for it.
-If this code was not requested by you, please contact us immediately.
+If you didn't request this code, please contact us immediately.
-Best regards,
-Your {{ instance }} team
+Thanks,
+The {{ instance }} Team
{% endblocktrans %}
diff --git a/src/pretix/control/templates/pretixcontrol/email/email_setup.txt b/src/pretix/control/templates/pretixcontrol/email/email_setup.txt
index d2b62a290..9635cab84 100644
--- a/src/pretix/control/templates/pretixcontrol/email/email_setup.txt
+++ b/src/pretix/control/templates/pretixcontrol/email/email_setup.txt
@@ -1,14 +1,15 @@
-{% load i18n %}{% blocktrans with code=code instance=instance %}Hello,
+{% load i18n %}{% blocktrans with code=code address=address instance=instance %}Hello,
-someone requested to use {{ address }} as a sender address on {{ instance }}.
-This will allow them to send emails that are shown to originate from this email address.
-If that was you, please enter the following confirmation code:
+Someone requested to use {{ address }} as a sender address on {{ instance }}. Once verified, emails sent from {{ instance }} can show this address as the sender.
-{{ code }}
+If this was you, enter the following code in the setup form:
-If this was not requested by you, you can safely ignore this email.
+ {{ code }}
-Best regards,
+Don't share this code with anyone. The {{ instance }} team will never ask you for it.
-Your {{ instance }} team
-{% endblocktrans %}
\ No newline at end of file
+If you didn't request this, you can safely ignore this email.
+
+Thanks,
+The {{ instance }} Team
+{% endblocktrans %}
diff --git a/src/pretix/control/templates/pretixcontrol/email/forgot.txt b/src/pretix/control/templates/pretixcontrol/email/forgot.txt
index a9292eb52..75d5b0f65 100644
--- a/src/pretix/control/templates/pretixcontrol/email/forgot.txt
+++ b/src/pretix/control/templates/pretixcontrol/email/forgot.txt
@@ -1,9 +1,11 @@
{% load i18n %}{% blocktrans with url=url|safe %}Hello,
-you requested a new password. Please go to the following page to reset your password:
+We received a request to reset the password for your {{ instance }} account. To choose a new password, follow the link below:
{{ url }}
-Best regards,
-Your {{ instance }} team
+If you didn't request this, you can safely ignore this email — your password won't change.
+
+Thanks,
+The {{ instance }} Team
{% endblocktrans %}
diff --git a/src/pretix/control/templates/pretixcontrol/email/invitation.txt b/src/pretix/control/templates/pretixcontrol/email/invitation.txt
index 7b3b6c160..c49efaa5b 100644
--- a/src/pretix/control/templates/pretixcontrol/email/invitation.txt
+++ b/src/pretix/control/templates/pretixcontrol/email/invitation.txt
@@ -1,17 +1,16 @@
{% load i18n %}{% blocktrans with url=url|safe %}Hello,
-you have been invited to a team on {{ instance }}, a platform to perform event
-ticket sales.
+You've been invited to join a team on {{ instance }}, an event ticket sales platform.
-Organizer: {{ organizer }}
-Team: {{ team }}
+- Organizer: {{ organizer }}
+- Team: {{ team }}
+
+To accept, follow the link below:
-If you want to join that team, just click on the following link:
{{ url }}
-If you do not want to join, you can safely ignore or delete this email.
+If you don't want to join, you can safely ignore this email.
-Best regards,
-
-Your {{ instance }} team
+Thanks,
+The {{ instance }} Team
{% endblocktrans %}
diff --git a/src/pretix/control/templates/pretixcontrol/email/login_notice.txt b/src/pretix/control/templates/pretixcontrol/email/login_notice.txt
index 44b8d01d1..0bd786690 100644
--- a/src/pretix/control/templates/pretixcontrol/email/login_notice.txt
+++ b/src/pretix/control/templates/pretixcontrol/email/login_notice.txt
@@ -1,13 +1,19 @@
-{% load i18n %}{% blocktrans with url=url|safe os=source.os_type agent=source.agent_type %}Hello,
+{% load i18n %}{% blocktrans %}Hello,
-a login to your {{ instance }} account from an unusual or new location was detected. The login was performed using {{ agent }} on {{ os }} from {{ country }}.
+We noticed a new sign-in to your {{ instance }} account:
+{% endblocktrans %}
+- {% trans "Time" %}: {{ when }}
+- {% trans "Browser" %}: {{ agent }}
+- {% trans "Operating system" %}: {{ os }}
+{% if device %}- {% trans "Device" %}: {{ device }}
+{% endif %}{% if country %}- {% trans "Country" %}: {{ country }}
+{% endif %}
+{% blocktrans with url=url|safe %}If it was you, no action is needed.
-If this was you, you can safely ignore this email.
-
-If this was not you, we recommend that you change your password in your account settings:
+If you don't recognise this sign-in, please change your password immediately:
{{ url }}
-Best regards,
-Your {{ instance }} team
+Thanks,
+The {{ instance }} Team
{% endblocktrans %}
diff --git a/src/pretix/control/templates/pretixcontrol/email/security_notice.txt b/src/pretix/control/templates/pretixcontrol/email/security_notice.txt
index a8f6531f3..8edcab067 100644
--- a/src/pretix/control/templates/pretixcontrol/email/security_notice.txt
+++ b/src/pretix/control/templates/pretixcontrol/email/security_notice.txt
@@ -1,16 +1,15 @@
{% load i18n %}{% blocktrans with url=url|safe messages=messages|safe %}Hello,
-this is to inform you that the account information of your {{ instance }} account has been
-changed. In particular, the following changes have been performed:
+The following changes were made to your {{ instance }} account:
{{ messages }}
-If this change was not performed by you, please contact us immediately.
+If you didn't make these changes, please contact the {{ instance }} support team immediately.
-You can review and change your account settings here:
+You can review your account settings here:
{{ url }}
-Best regards,
-Your {{ instance }} team
+Thanks,
+The {{ instance }} Team
{% endblocktrans %}
diff --git a/src/pretix/control/views/mailsetup.py b/src/pretix/control/views/mailsetup.py
index 6ef1f70fb..ceaede1ee 100644
--- a/src/pretix/control/views/mailsetup.py
+++ b/src/pretix/control/views/mailsetup.py
@@ -28,7 +28,7 @@ from django.core.mail import get_connection
from django.shortcuts import redirect
from django.utils.crypto import get_random_string
from django.utils.functional import cached_property
-from django.utils.translation import gettext_lazy as _
+from django.utils.translation import gettext, gettext_lazy as _
from django.views.generic import TemplateView
from pretix.base import email
@@ -216,13 +216,14 @@ class MailSettingsSetupView(TemplateView):
messages.error(request, _('The verification code was incorrect, please try again.'))
else:
self.request.session[session_key] = get_random_string(length=6, allowed_chars='1234567890')
+ sender_address = self.simple_form.cleaned_data.get('mail_from')
mail(
- self.simple_form.cleaned_data.get('mail_from'),
- _('Sender address verification'),
+ sender_address,
+ gettext('Confirm %(address)s as a sender address') % {'address': sender_address},
'pretixcontrol/email/email_setup.txt',
{
'code': self.request.session[session_key],
- 'address': self.simple_form.cleaned_data.get('mail_from'),
+ 'address': sender_address,
'instance': settings.PRETIX_INSTANCE_NAME,
},
None,
diff --git a/src/pretix/control/views/organizer.py b/src/pretix/control/views/organizer.py
index b891349df..62f26c899 100644
--- a/src/pretix/control/views/organizer.py
+++ b/src/pretix/control/views/organizer.py
@@ -1032,7 +1032,9 @@ class TeamMemberView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin,
def _send_invite(self, instance):
mail(
instance.email,
- _('Account invitation'),
+ gettext('You\'ve been invited to join %(organizer)s') % {
+ 'organizer': self.request.organizer.name,
+ },
'pretixcontrol/email/invitation.txt',
{
'instance': settings.PRETIX_INSTANCE_NAME,
diff --git a/src/pretix/helpers/security.py b/src/pretix/helpers/security.py
index b9aa92456..847aed36d 100644
--- a/src/pretix/helpers/security.py
+++ b/src/pretix/helpers/security.py
@@ -27,6 +27,7 @@ from django.conf import settings
from django.contrib.auth import login as auth_login
from django.contrib.gis import geoip2
from django.core.cache import cache
+from django.utils.formats import date_format
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django_countries.fields import Country
@@ -169,11 +170,15 @@ def handle_login_source(user, request):
with language(user.locale):
mail(
user.email,
- _('Login from new source detected'),
+ _('New sign-in to your account'),
'pretixcontrol/email/login_notice.txt',
{
- 'source': src,
- 'country': Country(str(country)).name if country else _('Unknown country'),
+ 'when': date_format(src.last_seen, 'DATETIME_FORMAT'),
+ 'agent': src.agent_type,
+ 'os': src.os_type,
+ # ua-parser returns "Other" for unidentified desktop devices.
+ 'device': src.device_type if src.device_type and src.device_type != 'Other' else None,
+ 'country': Country(str(country)).name if country else None,
'instance': settings.PRETIX_INSTANCE_NAME,
'url': mainreverse_absolute('control:user.settings')
},
diff --git a/src/tests/base/test_export.py b/src/tests/base/test_export.py
index 80c5deb87..7dab7d38c 100644
--- a/src/tests/base/test_export.py
+++ b/src/tests/base/test_export.py
@@ -104,7 +104,7 @@ def test_event_fail_invalid_config(event, user):
assert s.schedule_next_run > now()
assert s.error_counter == 1
assert len(djmail.outbox) == 1
- assert djmail.outbox[0].subject == "Export failed"
+ assert djmail.outbox[0].subject == "Scheduled export failed"
assert "Reason: Export type not found" in djmail.outbox[0].body
assert djmail.outbox[0].to == [user.email]
@@ -152,7 +152,7 @@ def test_event_fail_user_no_permission(event, user, team):
assert s.schedule_next_run > now()
assert s.error_counter == 1
assert len(djmail.outbox) == 1
- assert djmail.outbox[0].subject == "Export failed"
+ assert djmail.outbox[0].subject == "Scheduled export failed"
assert "Reason: Export type not found or permission denied." in djmail.outbox[0].body
assert djmail.outbox[0].to == [user.email]
@@ -235,7 +235,7 @@ def test_organizer_fail_invalid_config(event, user):
assert s.schedule_next_run > now()
assert s.error_counter == 1
assert len(djmail.outbox) == 1
- assert djmail.outbox[0].subject == "Export failed"
+ assert djmail.outbox[0].subject == "Scheduled export failed"
assert "Reason: Export type not found" in djmail.outbox[0].body
assert djmail.outbox[0].to == [user.email]
@@ -283,7 +283,7 @@ def test_organizer_fail_user_does_not_have_specific_permission(event, user, team
assert s.schedule_next_run > now()
assert s.error_counter == 1
assert len(djmail.outbox) == 1
- assert djmail.outbox[0].subject == "Export failed"
+ assert djmail.outbox[0].subject == "Scheduled export failed"
assert "Reason: Export type not found or permission denied." in djmail.outbox[0].body
assert djmail.outbox[0].to == [user.email]
+ {% trans "You're receiving this email based on your notification settings." %} - {% trans "Click here to view and change your notification settings" %} + {% trans "Manage settings" %} {% if disable_url %} - {% trans "Click here disable all notifications immediately." %} + {% trans "Disable all notifications" %} {% endif %} |