diff options
-rw-r--r-- | fietsboek/routes.py | 1 | ||||
-rw-r--r-- | fietsboek/templates/login.jinja2 | 2 | ||||
-rw-r--r-- | fietsboek/templates/resend_verification.jinja2 | 22 | ||||
-rw-r--r-- | fietsboek/views/default.py | 51 |
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> + • + <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 |