diff --git a/src/pretix/api/views/order.py b/src/pretix/api/views/order.py
index 887e1d059c..fdb076d849 100644
--- a/src/pretix/api/views/order.py
+++ b/src/pretix/api/views/order.py
@@ -482,6 +482,7 @@ class OrderViewSet(viewsets.ModelViewSet):
)
if 'email' in self.request.data and serializer.instance.email != self.request.data.get('email'):
+ serializer.instance.email_known_to_work = False
serializer.instance.log_action(
'pretix.event.order.contact.changed',
user=self.request.user,
diff --git a/src/pretix/base/migrations/0121_order_email_known_to_work.py b/src/pretix/base/migrations/0121_order_email_known_to_work.py
new file mode 100644
index 0000000000..5d5e90b5a9
--- /dev/null
+++ b/src/pretix/base/migrations/0121_order_email_known_to_work.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.1 on 2019-05-15 05:05
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('pretixbase', '0120_auto_20190509_0736'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='order',
+ name='email_known_to_work',
+ field=models.BooleanField(default=False),
+ ),
+ ]
diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py
index 567ad297c0..2a963b46d2 100644
--- a/src/pretix/base/models/orders.py
+++ b/src/pretix/base/models/orders.py
@@ -1,4 +1,5 @@
import copy
+import hashlib
import json
import logging
import os
@@ -180,6 +181,10 @@ class Order(LockModel, LoggedModel):
default=False
)
sales_channel = models.CharField(max_length=190, default="web")
+ email_known_to_work = models.BooleanField(
+ default=False,
+ verbose_name=_('E-mail address verified')
+ )
class Meta:
verbose_name = _("Order")
@@ -206,6 +211,9 @@ class Order(LockModel, LoggedModel):
self.event.cache.delete('complain_testmode_orders')
self.delete()
+ def email_confirm_hash(self):
+ return hashlib.sha256(settings.SECRET_KEY + self.secret.encode()).hexdigest()[:9]
+
@property
def fees(self):
"""
@@ -729,9 +737,10 @@ class Order(LockModel, LoggedModel):
email_template = self.event.settings.mail_text_resend_link
email_context = {
'event': self.event.name,
- 'url': build_absolute_uri(self.event, 'presale:event.order', kwargs={
+ 'url': build_absolute_uri(self.event, 'presale:event.order.open', kwargs={
'order': self.code,
- 'secret': self.secret
+ 'secret': self.secret,
+ 'hash': self.email_confirm_hash()
}),
'invoice_name': invoice_name,
'invoice_company': invoice_company,
@@ -1259,9 +1268,10 @@ class OrderPayment(models.Model):
email_template = self.order.event.settings.mail_text_order_paid
email_context = {
'event': self.order.event.name,
- 'url': build_absolute_uri(self.order.event, 'presale:event.order', kwargs={
+ 'url': build_absolute_uri(self.order.event, 'presale:event.order.open', kwargs={
'order': self.order.code,
- 'secret': self.order.secret
+ 'secret': self.order.secret,
+ 'hash': self.order.email_confirm_hash()
}),
'downloads': self.order.event.settings.get('ticket_download', as_type=bool),
'invoice_name': invoice_name,
diff --git a/src/pretix/base/services/mail.py b/src/pretix/base/services/mail.py
index e08634f60a..d2d42a2e4a 100644
--- a/src/pretix/base/services/mail.py
+++ b/src/pretix/base/services/mail.py
@@ -142,9 +142,10 @@ def mail(email: str, subject: str, template: Union[str, LazyI18nString],
"You can view your order details at the following URL:\n{orderurl}."
).replace("\n", "\r\n").format(
event=event.name, orderurl=build_absolute_uri(
- order.event, 'presale:event.order', kwargs={
+ order.event, 'presale:event.order.open', kwargs={
'order': order.code,
- 'secret': order.secret
+ 'secret': order.secret,
+ 'hash': order.email_confirm_hash()
}
)
)
diff --git a/src/pretix/base/services/orders.py b/src/pretix/base/services/orders.py
index 528717de07..ee4b4756bd 100644
--- a/src/pretix/base/services/orders.py
+++ b/src/pretix/base/services/orders.py
@@ -222,9 +222,10 @@ def approve_order(order, user=None, send_mail: bool=True, auth=None, force=False
'total_with_currency': LazyCurrencyNumber(order.total, order.event.currency),
'date': LazyDate(order.expires),
'event': order.event.name,
- 'url': build_absolute_uri(order.event, 'presale:event.order', kwargs={
+ 'url': build_absolute_uri(order.event, 'presale:event.order.open', kwargs={
'order': order.code,
- 'secret': order.secret
+ 'secret': order.secret,
+ 'hash': order.email_confirm_hash()
}),
'invoice_name': invoice_name,
'invoice_company': invoice_company,
@@ -282,9 +283,10 @@ def deny_order(order, comment='', user=None, send_mail: bool=True, auth=None):
'total_with_currency': LazyCurrencyNumber(order.total, order.event.currency),
'date': LazyDate(order.expires),
'event': order.event.name,
- 'url': build_absolute_uri(order.event, 'presale:event.order', kwargs={
+ 'url': build_absolute_uri(order.event, 'presale:event.order.open', kwargs={
'order': order.code,
- 'secret': order.secret
+ 'secret': order.secret,
+ 'hash': order.email_confirm_hash()
}),
'comment': comment,
'invoice_name': invoice_name,
@@ -375,9 +377,10 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
email_context = {
'event': order.event.name,
'code': order.code,
- 'url': build_absolute_uri(order.event, 'presale:event.order', kwargs={
+ 'url': build_absolute_uri(order.event, 'presale:event.order.open', kwargs={
'order': order.code,
- 'secret': order.secret
+ 'secret': order.secret,
+ 'hash': order.email_confirm_hash()
})
}
with language(order.locale):
@@ -730,9 +733,10 @@ def _perform_order(event: str, payment_provider: str, position_ids: List[str],
'total_with_currency': LazyCurrencyNumber(order.total, event.currency),
'date': LazyDate(order.expires),
'event': event.name,
- 'url': build_absolute_uri(event, 'presale:event.order', kwargs={
+ 'url': build_absolute_uri(event, 'presale:event.order.open', kwargs={
'order': order.code,
- 'secret': order.secret
+ 'secret': order.secret,
+ 'hash': order.email_confirm_hash()
}),
'payment_info': payment_info,
'invoice_name': invoice_name,
@@ -800,9 +804,10 @@ def send_expiry_warnings(sender, **kwargs):
email_template = eventsettings.mail_text_order_expire_warning
email_context = {
'event': o.event.name,
- 'url': build_absolute_uri(o.event, 'presale:event.order', kwargs={
+ 'url': build_absolute_uri(o.event, 'presale:event.order.open', kwargs={
'order': o.code,
- 'secret': o.secret
+ 'secret': o.secret,
+ 'hash': o.email_confirm_hash()
}),
'expire_date': date_format(o.expires.astimezone(tz), 'SHORT_DATE_FORMAT'),
'invoice_name': invoice_name,
@@ -851,9 +856,10 @@ def send_download_reminders(sender, **kwargs):
email_template = e.settings.mail_text_download_reminder
email_context = {
'event': o.event.name,
- 'url': build_absolute_uri(o.event, 'presale:event.order', kwargs={
+ 'url': build_absolute_uri(o.event, 'presale:event.order.open', kwargs={
'order': o.code,
- 'secret': o.secret
+ 'secret': o.secret,
+ 'hash': o.email_confirm_hash()
}),
}
email_subject = _('Your ticket is ready for download: %(code)s') % {'code': o.code}
@@ -1350,9 +1356,10 @@ class OrderChangeManager:
email_template = order.event.settings.mail_text_order_changed
email_context = {
'event': order.event.name,
- 'url': build_absolute_uri(self.order.event, 'presale:event.order', kwargs={
+ 'url': build_absolute_uri(self.order.event, 'presale:event.order.open', kwargs={
'order': order.code,
- 'secret': order.secret
+ 'secret': order.secret,
+ 'hash': order.email_confirm_hash()
}),
'invoice_name': invoice_name,
'invoice_company': invoice_company,
diff --git a/src/pretix/base/templates/pretixbase/email/plainwrapper.html b/src/pretix/base/templates/pretixbase/email/plainwrapper.html
index 264dac759a..f1ff19a682 100644
--- a/src/pretix/base/templates/pretixbase/email/plainwrapper.html
+++ b/src/pretix/base/templates/pretixbase/email/plainwrapper.html
@@ -27,7 +27,7 @@
{% trans "Event:" %} {{ event.name }}
{% trans "Order code:" %} {{ order.code }}
{% trans "Order date:" %} {{ order.datetime|date:"SHORT_DATE_FORMAT" }}
-
+
{% trans "View order details" %}
diff --git a/src/pretix/control/forms/orders.py b/src/pretix/control/forms/orders.py
index 4d11a05eeb..320f811005 100644
--- a/src/pretix/control/forms/orders.py
+++ b/src/pretix/control/forms/orders.py
@@ -340,7 +340,7 @@ class OrderContactForm(forms.ModelForm):
class Meta:
model = Order
- fields = ['email']
+ fields = ['email', 'email_known_to_work']
class OrderLocaleForm(forms.ModelForm):
diff --git a/src/pretix/control/templates/pretixcontrol/order/index.html b/src/pretix/control/templates/pretixcontrol/order/index.html
index 185400bef0..55a63d27df 100644
--- a/src/pretix/control/templates/pretixcontrol/order/index.html
+++ b/src/pretix/control/templates/pretixcontrol/order/index.html
@@ -136,7 +136,10 @@
{% endif %}