Skip to content

Commit

Permalink
More improv to email change
Browse files Browse the repository at this point in the history
  • Loading branch information
rafalp committed Jun 10, 2024
1 parent 3784d4b commit 573fee9
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 39 deletions.
6 changes: 0 additions & 6 deletions misago/account/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,12 +364,6 @@ def clean(self):
),
)

self.email_cache = cleaned_data["new_email"]

if not self.errors:
self["new_email"].value = ""
self["confirm_email"].value = ""

return cleaned_data


Expand Down
89 changes: 79 additions & 10 deletions misago/account/views/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

from django.conf import settings
from django.contrib import messages
from django.contrib.auth import logout
from django.contrib.auth import get_user_model, logout
from django.core.exceptions import PermissionDenied
from django.forms import Form
from django.http import Http404, HttpRequest, HttpResponse
from django.shortcuts import redirect, render
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.translation import gettext as _, pgettext, pgettext_lazy
from django.views import View

Expand Down Expand Up @@ -36,6 +36,8 @@
)
from ..menus import account_settings_menu

User = get_user_model()


def raise_if_not_authenticated(request):
if not request.user.is_authenticated:
Expand Down Expand Up @@ -103,15 +105,21 @@ def get(self, request: HttpRequest) -> HttpResponse:
def post(self, request: HttpRequest) -> HttpResponse:
form = self.get_form_instance(request)
if form.is_valid():
self.save_form(request, form)
return self.handle_valid_form(request, form)

messages.success(request, self.success_message)
return self.handle_invalid_form(request, form)

def handle_valid_form(self, request: HttpRequest, form: Form) -> HttpResponse:
self.save_form(request, form)

if request.is_htmx and self.template_htmx_name:
return self.render(request, self.template_htmx_name, {"form": form})
messages.success(request, self.success_message)

if request.is_htmx and self.template_htmx_name:
return self.render(request, self.template_htmx_name, {"form": form})

return redirect(request.path_info)
return redirect(request.path_info)

def handle_invalid_form(self, request: HttpRequest, form: Form) -> HttpResponse:
messages.error(request, _("Form contains errors"))

if request.is_htmx and self.template_htmx_name:
Expand Down Expand Up @@ -273,10 +281,11 @@ def save_form(self, request: HttpRequest, form: Form) -> None:
class AccountEmailView(AccountSettingsFormView):
template_name = "misago/account/settings/email.html"
template_htmx_name = "misago/account/settings/email_form.html"
email_template_name = "misago/emails/email_change_confirm"
template_htmx_success_name = "misago/account/settings/email_form_completed.html"
email_template_name = "misago/emails/email_confirm_change"

success_message = pgettext_lazy(
"account settings email confirm", "Confirm email change"
"account settings email confirm", "Confirmation email sent"
)

def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
Expand All @@ -285,6 +294,16 @@ def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpRespo

return super().dispatch(request, *args, **kwargs)

def get(self, request: HttpRequest) -> HttpResponse:
form = self.get_form_instance(request)

if request.is_htmx:
template_name = self.template_htmx_name
else:
template_name = self.template_name

return self.render(request, template_name, {"form": form})

def get_form_instance(self, request: HttpRequest) -> AccountEmailForm:
if request.method == "POST":
return AccountEmailForm(
Expand All @@ -298,6 +317,20 @@ def get_form_instance(self, request: HttpRequest) -> AccountEmailForm:
request=request,
)

def handle_valid_form(self, request: HttpRequest, form: Form) -> HttpResponse:
self.save_form(request, form)

if request.is_htmx and self.template_htmx_name:
messages.success(request, self.success_message)
return self.render(
request,
self.template_htmx_success_name,
{"new_email": form.cleaned_data["new_email"]},
)

request.session["misago_new_email"] = form.cleaned_data["new_email"]
return redirect(request.path_info)

def save_form(self, request: HttpRequest, form: Form) -> None:
new_email = form.cleaned_data["new_email"]
token = create_email_change_token(request.user, form.cleaned_data["new_email"])
Expand All @@ -308,7 +341,7 @@ def save_form(self, request: HttpRequest, form: Form) -> None:
mail = build_mail(
request.user,
pgettext(
"email change confirm email subject",
"email confirm change email subject",
"Change your email on the %(forum_name)s forums",
)
% {"forum_name": request.settings.forum_name},
Expand All @@ -322,6 +355,42 @@ def save_form(self, request: HttpRequest, form: Form) -> None:
mail.send(fail_silently=True)


def account_email_change_confirm_sent(request):
new_email = request.session.pop("misago_new_email", None)
if not new_email:
raise Http404()

return render(
request,
"misago/account/settings/email_confirm_sent.html",
{"new_email": new_email},
)


def account_email_change_confirm(request, user_id, token):
user = get_object_or_404(User.objects, id=user_id, is_active=True)

try:
new_email = read_email_change_token(user, token)
except EmailChangeTokenError:
raise NotImplementedError("TODO")

# TODO: verify user is not banned
# TODO: verify new email is still valid

if new_email != user.email:
user.set_email(new_email)
user.save()

# TODO: write template
# TODO: write tests
return render(
request,
"misago/account/settings/email_changed.html",
{"username": user.username},
)


class AccountDownloadDataView(AccountSettingsView):
template_name = "misago/account/settings/download_data.html"
template_htmx_name = "misago/account/settings/download_data_form.html"
Expand Down
17 changes: 0 additions & 17 deletions misago/templates/misago/account/settings/email_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,6 @@
{% include "misago/snackbars.html" %}
{% endif %}
<div id="misago-htmx-root">
{% if form.email_cache %}
<div class="panel panel-default panel-form">
<div class="panel-heading">
<h3 class="panel-title">
{% trans "Confirm email address change" context "account email page" %}
</h3>
</div>
<div class="panel-body">
{% capture trimmed as new_email %}
<strong>{{ form.email_cache }}</strong>
{% endcapture %}
{% blocktrans trimmed with email=new_email|safe context "account email page" %}
To confirm the change of your email address please click the confirmation link in a message that was sent to "{{ email }}".
{% endblocktrans %}
</div>
</div>
{% endif %}
<form
action="{% url 'misago:account-email' %}"
method="post"
Expand Down
34 changes: 34 additions & 0 deletions misago/templates/misago/account/settings/email_form_completed.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{% load i18n misago_forms misago_capture %}
{% if is_request_htmx %}
{% include "misago/snackbars.html" %}
{% endif %}
<div id="misago-htmx-root">
<div class="panel panel-default panel-form">
<div class="panel-heading">
<h3 class="panel-title">
{% trans "Confirm email address change" context "account email page" %}
</h3>
</div>
<div class="panel-body">
{% capture trimmed as new_email %}
<strong>{{ new_email }}</strong>
{% endcapture %}
<p>
{% blocktrans trimmed with email=new_email|safe context "account email page" %}
To confirm the change of your email address please click the confirmation link in a message that was sent to "{{ email }}".
{% endblocktrans %}
</p>
</div>
<div class="panel-footer panel-footer-sticky">
<a
href="{% url 'misago:account-email' %}"
class="btn btn-default"
hx-get="{% url 'misago:account-email' %}"
hx-target="#misago-htmx-root"
hx-swap="outerHTML"
>
{% trans "Go back" context "account email go back btn" %}
</a>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@


{% block content %}
{% blocktrans trimmed with user=user context "email change confirm email" %}
{% blocktrans trimmed with user=user context "email confirm change email" %}
{{ user }}, you are receiving this message because you are changing your e-mail address.
{% endblocktrans %}
<br>
<br>
<a href="{{ settings.forum_address }}{{ token }}">{% trans "Confirm change" context "email change confirm email cta" %}</a>
<a href="{{ settings.forum_address }}{{ token }}">{% trans "Confirm change" context "email confirm change email cta" %}</a>
<br>
<br>
{% blocktrans trimmed count expires_in=expires_in context "email change confirm email" %}
{% blocktrans trimmed count expires_in=expires_in context "email confirm change email" %}
This link will remain active for {{ expires_in }} hour from the time this message has been sent.
{% plural %}
This link will remain active for {{ expires_in }} hours from the time this message has been sent.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@


{% block content %}
{% blocktrans trimmed with user=user context "email change confirm email" %}
{% blocktrans trimmed with user=user context "email confirm change email" %}
{{ user }}, you are receiving this message because you are changing your e-mail address.
{% endblocktrans %}

{% blocktrans trimmed context "email change confirm email" %}
{% blocktrans trimmed context "email confirm change email" %}
To confirm the change, click the following link:
{% endblocktrans %}
{{ settings.forum_address }}{{ token }}

{% blocktrans trimmed count expires_in=expires_in context "email change confirm email" %}
{% blocktrans trimmed count expires_in=expires_in context "email confirm change email" %}
This link will remain active for {{ expires_in }} hour from the time this message has been sent.
{% plural %}
This link will remain active for {{ expires_in }} hours from the time this message has been sent.
Expand Down

0 comments on commit 573fee9

Please sign in to comment.