aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fietsboek/routes.py1
-rw-r--r--fietsboek/templates/login.jinja22
-rw-r--r--fietsboek/templates/resend_verification.jinja222
-rw-r--r--fietsboek/views/default.py51
4 files changed, 76 insertions, 0 deletions
diff --git a/fietsboek/routes.py b/fietsboek/routes.py
index 8f109d9..60a566d 100644
--- a/fietsboek/routes.py
+++ b/fietsboek/routes.py
@@ -14,6 +14,7 @@ def includeme(config):
config.add_route("track-archive", "/track/archive")
config.add_route("password-reset", "/password-reset")
+ config.add_route("resend-verification", "/resend-verification")
config.add_route("use-token", "/token/{uuid}")
config.add_route("create-account", "/create-account")
diff --git a/fietsboek/templates/login.jinja2 b/fietsboek/templates/login.jinja2
index 7a9bf07..bdf2c99 100644
--- a/fietsboek/templates/login.jinja2
+++ b/fietsboek/templates/login.jinja2
@@ -41,6 +41,8 @@
<div class="row justify-content-center">
<div class="col-auto mb-3">
<a href="{{ request.route_url("password-reset") }}">{{ _("page.login.forgot_password") }}</a>
+ &bull;
+ <a href="{{ request.route_url("resend-verification") }}">{{ _("page.login.resend_verification") }}</a>
</div>
</div>
</form>
diff --git a/fietsboek/templates/resend_verification.jinja2 b/fietsboek/templates/resend_verification.jinja2
new file mode 100644
index 0000000..cc56854
--- /dev/null
+++ b/fietsboek/templates/resend_verification.jinja2
@@ -0,0 +1,22 @@
+{% extends "layout.jinja2" %}
+{% import "util.jinja2" as util with context %}
+{% block content %}
+<div class="container">
+ <h1>{{ _("page.resend_verification.title") }}</h1>
+ <p>{{ _("page.resend_verification.info") }}</p>
+ <form method="POST">
+ <div class="row align-items-center">
+ <div class="col-lg-5">
+ <div class="form-floating">
+ <input type="email" id="resendEmail" name="email" class="form-control" placeholder="x">
+ <label for="resendEmail">{{ _("page.resend_verification.email") }}</label>
+ </div>
+ </div>
+ {{ util.hidden_csrf_input() }}
+ <div class="col-lg-4">
+ <button class="btn btn-primary">{{ _("page.resend_verification.request") }}</button>
+ </div>
+ </div>
+ </form>
+</div>
+{% endblock %}
diff --git a/fietsboek/views/default.py b/fietsboek/views/default.py
index b8b1835..397f9ca 100644
--- a/fietsboek/views/default.py
+++ b/fietsboek/views/default.py
@@ -196,6 +196,57 @@ def do_password_reset(request: Request) -> Response:
return HTTPFound(request.route_url("password-reset"))
+@view_config(
+ route_name="resend-verification",
+ request_method="GET",
+ renderer="fietsboek:templates/resend_verification.jinja2",
+)
+def resend_verification(request: Request) -> Response:
+ """Form to request a new verification mail.
+
+ :param request: The Pyramid request.
+ :return: The HTTP response.
+ """
+ return {}
+
+
+@view_config(route_name="resend-verification", request_method="POST")
+def do_resend_verification(request: Request) -> Response:
+ """Endpoint for the verification resend form.
+
+ :param request: The Pyramid request.
+ :return: The HTTP response.
+ """
+ query = models.User.query_by_email(request.params["email"])
+ user = request.dbsession.execute(query).scalar_one_or_none()
+ if user is None or user.is_verified:
+ request.session.flash(request.localizer.translate(_("flash.resend_verification_email")))
+ return HTTPFound(request.route_url("resend-verification"))
+
+ token = models.Token.generate(user, TokenType.VERIFY_EMAIL)
+ request.dbsession.add(token)
+ request.session.flash(request.localizer.translate(_("flash.verification_token_generated")))
+
+ mail = email.prepare_message(
+ request.config.email_from,
+ user.email,
+ request.localizer.translate(_("page.password_reset.email.subject")),
+ )
+ mail.set_content(
+ request.localizer.translate(_("page.password_reset.email.body")).format(
+ request.route_url("use-token", uuid=token.uuid)
+ )
+ )
+ email.send_message(
+ request.config.email_smtp_url,
+ request.config.email_username,
+ request.config.email_password.get_secret_value(),
+ mail,
+ )
+
+ return HTTPFound(request.route_url("password-reset"))
+
+
@view_config(route_name="use-token")
def use_token(request: Request) -> Response:
"""Endpoint with which a user can use a token for a password reset or email