mirror of
https://forgejo.ellis.link/continuwuation/continuwuity/
synced 2026-05-13 08:44:53 +00:00
refactor: Use more consistent terminology for email validation pages
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
use askama::Template;
|
||||
use async_trait::async_trait;
|
||||
use conduwuit::{Result, info, utils::ReadyExt};
|
||||
use futures::{FutureExt, StreamExt};
|
||||
use futures::StreamExt;
|
||||
use ruma::{UserId, events::room::message::RoomMessageEventContent};
|
||||
|
||||
use crate::{
|
||||
|
||||
@@ -25,13 +25,13 @@
|
||||
|
||||
pub(crate) fn build() -> Router<crate::State> {
|
||||
Router::new()
|
||||
.route("/change/", on(GET_POST, route_change_email_request))
|
||||
.route("/change/validate", get(get_change_email))
|
||||
.route("/change/", on(GET_POST, route_change_email))
|
||||
.route("/change/validate", get(get_change_email_validate))
|
||||
.route("/change/delete", post(post_delete_email))
|
||||
}
|
||||
|
||||
template! {
|
||||
struct ChangeEmailRequest use "change_email_request.html.j2" {
|
||||
struct ChangeEmail use "change_email.html.j2" {
|
||||
user_card: UserCard,
|
||||
email: Option<String>,
|
||||
form: Form<'static>,
|
||||
@@ -40,7 +40,7 @@ struct ChangeEmailRequest use "change_email_request.html.j2" {
|
||||
}
|
||||
|
||||
form! {
|
||||
struct ChangeEmailRequestForm {
|
||||
struct ChangeEmailForm {
|
||||
email: Address where {
|
||||
input_type: "email",
|
||||
label: "Email address"
|
||||
@@ -51,9 +51,9 @@ struct ChangeEmailRequestForm {
|
||||
}
|
||||
|
||||
template! {
|
||||
struct ChangeEmail use "change_email.html.j2" {
|
||||
struct ChangeEmailValidate use "change_email_validate.html.j2" {
|
||||
user_card: UserCard,
|
||||
body: ChangeEmailBody
|
||||
body: ChangeEmailValidateBody
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ struct DeleteEmail use "delete_email.html.j2" {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ChangeEmailBody {
|
||||
enum ChangeEmailValidateBody {
|
||||
ValidationPending {
|
||||
session_id: OwnedSessionId,
|
||||
client_secret: OwnedClientSecret,
|
||||
@@ -73,16 +73,16 @@ enum ChangeEmailBody {
|
||||
Success,
|
||||
}
|
||||
|
||||
async fn route_change_email_request(
|
||||
async fn route_change_email(
|
||||
State(services): State<crate::State>,
|
||||
Extension(context): Extension<TemplateContext>,
|
||||
user: User,
|
||||
PostForm(form): PostForm<ChangeEmailRequestForm>,
|
||||
PostForm(form): PostForm<ChangeEmailForm>,
|
||||
) -> Result {
|
||||
let user_id = user.expect_recent(LoginTarget::ChangeEmail)?;
|
||||
|
||||
let Some(form) = form else {
|
||||
return response!(ChangeEmailRequest::new(
|
||||
return response!(ChangeEmail::new(
|
||||
context.clone(),
|
||||
UserCard::for_local_user(&services, user_id.clone()).await,
|
||||
services
|
||||
@@ -90,7 +90,7 @@ async fn route_change_email_request(
|
||||
.get_email_for_localpart(user_id.localpart())
|
||||
.await
|
||||
.map(|address| address.to_string()),
|
||||
ChangeEmailRequestForm::build(context),
|
||||
ChangeEmailForm::build(context),
|
||||
services.threepid.email_requirement().may_remove(),
|
||||
));
|
||||
};
|
||||
@@ -128,10 +128,10 @@ async fn route_change_email_request(
|
||||
}
|
||||
};
|
||||
|
||||
response!(ChangeEmail::new(
|
||||
response!(ChangeEmailValidate::new(
|
||||
context,
|
||||
UserCard::for_local_user(&services, user_id).await,
|
||||
ChangeEmailBody::ValidationPending {
|
||||
ChangeEmailValidateBody::ValidationPending {
|
||||
session_id,
|
||||
client_secret,
|
||||
validation_error: false
|
||||
@@ -145,7 +145,7 @@ struct ChangeEmailQuery {
|
||||
threepid: ThreepidQuery,
|
||||
}
|
||||
|
||||
async fn get_change_email(
|
||||
async fn get_change_email_validate(
|
||||
State(services): State<crate::State>,
|
||||
Extension(context): Extension<TemplateContext>,
|
||||
Expect(Query(ChangeEmailQuery {
|
||||
@@ -165,10 +165,10 @@ async fn get_change_email(
|
||||
.get_valid_session(&session_id, &client_secret)
|
||||
.await
|
||||
else {
|
||||
return response!(ChangeEmail::new(
|
||||
return response!(ChangeEmailValidate::new(
|
||||
context,
|
||||
user_card,
|
||||
ChangeEmailBody::ValidationPending {
|
||||
ChangeEmailValidateBody::ValidationPending {
|
||||
session_id,
|
||||
client_secret,
|
||||
validation_error: true
|
||||
@@ -186,7 +186,7 @@ async fn get_change_email(
|
||||
return response!(BadRequest(err.message()));
|
||||
}
|
||||
|
||||
response!(ChangeEmail::new(context, user_card, ChangeEmailBody::Success))
|
||||
response!(ChangeEmailValidate::new(context, user_card, ChangeEmailValidateBody::Success))
|
||||
}
|
||||
|
||||
async fn post_delete_email(
|
||||
|
||||
@@ -28,18 +28,18 @@
|
||||
|
||||
pub(crate) fn build() -> Router<crate::State> {
|
||||
Router::new()
|
||||
.route("/", on(GET_POST, route_reset_password_request))
|
||||
.route("/validate", on(GET_POST, route_reset_password))
|
||||
.route("/", on(GET_POST, route_reset_password))
|
||||
.route("/validate", on(GET_POST, route_reset_password_validate))
|
||||
}
|
||||
|
||||
template! {
|
||||
struct ResetPasswordRequest use "reset_password_request.html.j2" {
|
||||
body: ResetPasswordRequestBody
|
||||
struct ResetPassword use "reset_password.html.j2" {
|
||||
body: ResetPasswordBody
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ResetPasswordRequestBody {
|
||||
enum ResetPasswordBody {
|
||||
Form(Form<'static>),
|
||||
Unavailable,
|
||||
}
|
||||
@@ -55,24 +55,21 @@ struct ResetPasswordRequestForm {
|
||||
}
|
||||
}
|
||||
|
||||
async fn route_reset_password_request(
|
||||
async fn route_reset_password(
|
||||
State(services): State<crate::State>,
|
||||
Extension(context): Extension<TemplateContext>,
|
||||
PostForm(form): PostForm<ResetPasswordRequestForm>,
|
||||
) -> Result {
|
||||
// Check if SMTP is configured
|
||||
if services.mailer.mailer().is_none() {
|
||||
return response!(ResetPasswordRequest::new(
|
||||
context,
|
||||
ResetPasswordRequestBody::Unavailable
|
||||
));
|
||||
return response!(ResetPassword::new(context, ResetPasswordBody::Unavailable));
|
||||
}
|
||||
|
||||
let Some(form) = form else {
|
||||
// For GET requests return the reset request form
|
||||
return response!(ResetPasswordRequest::new(
|
||||
return response!(ResetPassword::new(
|
||||
context.clone(),
|
||||
ResetPasswordRequestBody::Form(ResetPasswordRequestForm::build(context))
|
||||
ResetPasswordBody::Form(ResetPasswordRequestForm::build(context))
|
||||
));
|
||||
};
|
||||
|
||||
@@ -118,21 +115,24 @@ async fn route_reset_password_request(
|
||||
ValidationSessions::generate_session_id()
|
||||
});
|
||||
|
||||
response!(ResetPassword::new(context, ResetPasswordBody::ValidationPending {
|
||||
client_secret,
|
||||
session_id,
|
||||
validation_error: false
|
||||
}))
|
||||
response!(ResetPasswordValidate::new(
|
||||
context,
|
||||
ResetPasswordValidateBody::ValidationPending {
|
||||
client_secret,
|
||||
session_id,
|
||||
validation_error: false
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
template! {
|
||||
struct ResetPassword use "reset_password.html.j2" {
|
||||
body: ResetPasswordBody
|
||||
struct ResetPasswordValidate use "reset_password_validate.html.j2" {
|
||||
body: ResetPasswordValidateBody
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ResetPasswordBody {
|
||||
enum ResetPasswordValidateBody {
|
||||
ValidationPending {
|
||||
session_id: OwnedSessionId,
|
||||
client_secret: OwnedClientSecret,
|
||||
@@ -173,7 +173,7 @@ struct ResetPasswordQuery {
|
||||
threepid: ThreepidQuery,
|
||||
}
|
||||
|
||||
async fn route_reset_password(
|
||||
async fn route_reset_password_validate(
|
||||
State(services): State<crate::State>,
|
||||
Extension(context): Extension<TemplateContext>,
|
||||
Expect(Query(query)): Expect<Query<ResetPasswordQuery>>,
|
||||
@@ -203,7 +203,7 @@ async fn route_reset_password(
|
||||
|
||||
if let Some(form) = form {
|
||||
if let Err(err) = form.validate() {
|
||||
ResetPasswordBody::ValidationSuccess {
|
||||
ResetPasswordValidateBody::ValidationSuccess {
|
||||
user_card,
|
||||
form: ResetPasswordForm::with_errors(context.clone(), err),
|
||||
}
|
||||
@@ -214,7 +214,7 @@ async fn route_reset_password(
|
||||
|
||||
services.users.set_password(&user_id, Some(hash));
|
||||
|
||||
ResetPasswordBody::ResetSuccess { user_card }
|
||||
ResetPasswordValidateBody::ResetSuccess { user_card }
|
||||
},
|
||||
| Err(err) => {
|
||||
let mut errors = ValidationErrors::new();
|
||||
@@ -225,7 +225,7 @@ async fn route_reset_password(
|
||||
.with_message(err.message().into()),
|
||||
);
|
||||
|
||||
ResetPasswordBody::ValidationSuccess {
|
||||
ResetPasswordValidateBody::ValidationSuccess {
|
||||
user_card,
|
||||
form: ResetPasswordForm::with_errors(context.clone(), errors),
|
||||
}
|
||||
@@ -233,18 +233,18 @@ async fn route_reset_password(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ResetPasswordBody::ValidationSuccess {
|
||||
ResetPasswordValidateBody::ValidationSuccess {
|
||||
user_card,
|
||||
form: ResetPasswordForm::build(context.clone()),
|
||||
}
|
||||
}
|
||||
},
|
||||
| Err(_) => ResetPasswordBody::ValidationPending {
|
||||
| Err(_) => ResetPasswordValidateBody::ValidationPending {
|
||||
session_id: query.threepid.session_id,
|
||||
client_secret: query.threepid.client_secret,
|
||||
validation_error: true,
|
||||
},
|
||||
};
|
||||
|
||||
response!(ResetPassword::new(context, body))
|
||||
response!(ResetPasswordValidate::new(context, body))
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
pub(crate) fn build() -> Router<crate::State> {
|
||||
Router::new()
|
||||
.route("/", on(GET_POST, route_register))
|
||||
.route("/validate", get(get_register_confirm_email))
|
||||
.route("/validate", get(get_register_email_validate))
|
||||
}
|
||||
|
||||
template! {
|
||||
@@ -225,7 +225,7 @@ async fn route_register(
|
||||
}
|
||||
|
||||
template! {
|
||||
struct RegisterConfirmEmail use "register_confirm_email.html.j2" {
|
||||
struct RegisterEmailValidate use "register_email_validate.html.j2" {
|
||||
session_id: OwnedSessionId,
|
||||
client_secret: OwnedClientSecret,
|
||||
validation_error: bool
|
||||
@@ -233,18 +233,18 @@ struct RegisterConfirmEmail use "register_confirm_email.html.j2" {
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
struct RegisterConfirmEmailQuery {
|
||||
struct RegisterEmailValidateQuery {
|
||||
#[serde(flatten)]
|
||||
threepid: ThreepidQuery,
|
||||
}
|
||||
|
||||
async fn get_register_confirm_email(
|
||||
async fn get_register_email_validate(
|
||||
State(services): State<crate::State>,
|
||||
Extension(context): Extension<TemplateContext>,
|
||||
session_store: Session,
|
||||
Expect(Query(RegisterConfirmEmailQuery {
|
||||
Expect(Query(RegisterEmailValidateQuery {
|
||||
threepid: ThreepidQuery { client_secret, session_id },
|
||||
})): Expect<Query<RegisterConfirmEmailQuery>>,
|
||||
})): Expect<Query<RegisterEmailValidateQuery>>,
|
||||
) -> Result {
|
||||
let Some(completed_registration) = session_store
|
||||
.get::<CompletedRegistration>(COMPLETED_REGISTRATION_KEY)
|
||||
@@ -261,7 +261,7 @@ async fn get_register_confirm_email(
|
||||
.get_valid_session(&session_id, &client_secret)
|
||||
.await
|
||||
else {
|
||||
return response!(RegisterConfirmEmail::new(context, session_id, client_secret, true,));
|
||||
return response!(RegisterEmailValidate::new(context, session_id, client_secret, true,));
|
||||
};
|
||||
|
||||
let email = session.consume();
|
||||
@@ -451,7 +451,9 @@ async fn begin_registration(
|
||||
.await
|
||||
.expect("should have been able to serialize completed registration");
|
||||
|
||||
Ok(response!(RegisterConfirmEmail::new(context, session_id, client_secret, false,)))
|
||||
Ok(response!(
|
||||
RegisterEmailValidate::new(context, session_id, client_secret, false,)
|
||||
))
|
||||
} else {
|
||||
// If email isn't required we can immediately complete registration
|
||||
complete_registration(services, session_store, completed_registration, None).await;
|
||||
|
||||
@@ -5,29 +5,31 @@ Change your email
|
||||
{%- endblock -%}
|
||||
|
||||
{%- block content -%}
|
||||
<div class="panel narrow">
|
||||
<h1>Change your email</h1>
|
||||
<div class="panel">
|
||||
<h1>Change your email <a class="back" href="{{ crate::ROUTE_PREFIX }}/account/">Back</a></h1>
|
||||
{{ user_card }}
|
||||
{% match body %}
|
||||
{% when ChangeEmailBody::ValidationPending { session_id, client_secret, validation_error } %}
|
||||
<p>
|
||||
A message has been sent to your new email address with a validation link. If you do not receive the email:
|
||||
<ul>
|
||||
<li>Check your spam filter.</li>
|
||||
</ul>
|
||||
</p>
|
||||
{% if validation_error %}
|
||||
<small class="error">Validation failed. Have you clicked the link in the email that was sent to you?</small>
|
||||
{% endif %}
|
||||
<form method="get" action="validate">
|
||||
<input type="hidden" name="session_id" value="{{ session_id }}">
|
||||
<input type="hidden" name="client_secret" value="{{ client_secret }}">
|
||||
<button type="submit">Continue</button>
|
||||
</form>
|
||||
{% when ChangeEmailBody::Success %}
|
||||
<p>
|
||||
Your email address has been changed successfully. <a href="{{ crate::ROUTE_PREFIX }}/account/">Back</a>
|
||||
</p>
|
||||
{% endmatch %}
|
||||
<p>
|
||||
Your email address will be used for automated emails, such as password reset requests. It is also
|
||||
visible to your homeserver's administrator, who may use it to contact you directly.
|
||||
</p>
|
||||
<p>
|
||||
{% if let Some(email) = email %}
|
||||
Your account's associated email address is <code>{{ email }}</code>.
|
||||
To change your email address, enter your new address below.
|
||||
{% else %}
|
||||
Your account has no associated email address. To add an email address, enter it below.
|
||||
{% endif %}
|
||||
</p>
|
||||
{{ form }}
|
||||
|
||||
{% if may_remove %}
|
||||
<p>
|
||||
You may remove your email address. Note that, if your account has no email address,
|
||||
you will not be able to reset your password if you forget it.
|
||||
</p>
|
||||
<form method="post" action="delete">
|
||||
<button type="submit">Remove your email address</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{%- endblock -%}
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
{% extends "_layout.html.j2" %}
|
||||
|
||||
{%- block title -%}
|
||||
Change your email
|
||||
{%- endblock -%}
|
||||
|
||||
{%- block content -%}
|
||||
<div class="panel">
|
||||
<h1>Change your email <a class="back" href="{{ crate::ROUTE_PREFIX }}/account/">Back</a></h1>
|
||||
{{ user_card }}
|
||||
<p>
|
||||
Your email address will be used for automated emails, such as password reset requests. It is also
|
||||
visible to your homeserver's administrator, who may use it to contact you directly.
|
||||
</p>
|
||||
<p>
|
||||
{% if let Some(email) = email %}
|
||||
Your account's associated email address is <code>{{ email }}</code>.
|
||||
To change your email address, enter your new address below.
|
||||
{% else %}
|
||||
Your account has no associated email address. To add an email address, enter it below.
|
||||
{% endif %}
|
||||
</p>
|
||||
{{ form }}
|
||||
|
||||
{% if may_remove %}
|
||||
<p>
|
||||
You may remove your email address. Note that, if your account has no email address,
|
||||
you will not be able to reset your password if you forget it.
|
||||
</p>
|
||||
<form method="post" action="delete">
|
||||
<button type="submit">Remove your email address</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,33 @@
|
||||
{% extends "_layout.html.j2" %}
|
||||
|
||||
{%- block title -%}
|
||||
Change your email
|
||||
{%- endblock -%}
|
||||
|
||||
{%- block content -%}
|
||||
<div class="panel narrow">
|
||||
<h1>Change your email</h1>
|
||||
{{ user_card }}
|
||||
{% match body %}
|
||||
{% when ChangeEmailValidateBody::ValidationPending { session_id, client_secret, validation_error } %}
|
||||
<p>
|
||||
A message has been sent to your new email address with a validation link. If you do not receive the email:
|
||||
<ul>
|
||||
<li>Check your spam filter.</li>
|
||||
</ul>
|
||||
</p>
|
||||
{% if validation_error %}
|
||||
<small class="error">Validation failed. Have you clicked the link in the email that was sent to you?</small>
|
||||
{% endif %}
|
||||
<form method="get" action="validate">
|
||||
<input type="hidden" name="session_id" value="{{ session_id }}">
|
||||
<input type="hidden" name="client_secret" value="{{ client_secret }}">
|
||||
<button type="submit">Continue</button>
|
||||
</form>
|
||||
{% when ChangeEmailValidateBody::Success %}
|
||||
<p>
|
||||
Your email address has been changed successfully. <a href="{{ crate::ROUTE_PREFIX }}/account/">Back</a>
|
||||
</p>
|
||||
{% endmatch %}
|
||||
</div>
|
||||
{%- endblock -%}
|
||||
@@ -85,6 +85,7 @@ Sign up
|
||||
<span>:{{ server_name }}</span>
|
||||
</span>
|
||||
{{ form::errors(field_errors, std::borrow::Cow::Borrowed("username")) }}
|
||||
<small><b>Note:</b> Your username cannot be changed after you create your account.</small>
|
||||
</p>
|
||||
<p>
|
||||
Just a few more details to finish creating your account.
|
||||
|
||||
@@ -5,32 +5,28 @@ Reset your password
|
||||
{%- endblock -%}
|
||||
|
||||
{%- block content -%}
|
||||
<div class="panel narrow">
|
||||
{% match body %}
|
||||
{% when ResetPasswordBody::Form(_) %}
|
||||
<div class="panel">
|
||||
{% when ResetPasswordBody::Unavailable %}
|
||||
<div class="panel middle"/>
|
||||
{% endmatch %}
|
||||
<h1>Reset your password</h1>
|
||||
{% match body %}
|
||||
{% when ResetPasswordBody::ValidationPending { session_id, client_secret, validation_error } %}
|
||||
{% when ResetPasswordBody::Form(form) %}
|
||||
<p>
|
||||
Check your inbox for the validation email. If you do not receive the email:
|
||||
<ul>
|
||||
<li>Check your spam filter.</li>
|
||||
<li>Your Matrix account may not be associated with an email address. Contact your homeserver's
|
||||
administrator for assistance.</li>
|
||||
</ul>
|
||||
To reset your password, enter your email below. If your Matrix account has an associated email address,
|
||||
you will receive an email with a link to reset your password.
|
||||
</p>
|
||||
<p>
|
||||
If your Matrix account does not have an associated email address, contact your homeserver's administrator
|
||||
to reset your password.
|
||||
</p>
|
||||
{% if validation_error %}
|
||||
<small class="error">Validation failed. Have you clicked the link in the email that was sent to you?</small>
|
||||
{% endif %}
|
||||
<form method="get" action="validate">
|
||||
<input type="hidden" name="session_id" value="{{ session_id }}">
|
||||
<input type="hidden" name="client_secret" value="{{ client_secret }}">
|
||||
<button type="submit">Continue</button>
|
||||
</form>
|
||||
{% when ResetPasswordBody::ValidationSuccess { user_card, form } %}
|
||||
{{ user_card }}
|
||||
{{ form }}
|
||||
{% when ResetPasswordBody::ResetSuccess { user_card } %}
|
||||
{{ user_card }}
|
||||
<p>Your password has been reset successfully.</p>
|
||||
{% when ResetPasswordBody::Unavailable %}
|
||||
<p>
|
||||
To reset your password, contact your homeserver's administrator.
|
||||
</p>
|
||||
{% endmatch %}
|
||||
</div>
|
||||
{%- endblock -%}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
{% extends "_layout.html.j2" %}
|
||||
|
||||
{%- block title -%}
|
||||
Reset your password
|
||||
{%- endblock -%}
|
||||
|
||||
{%- block content -%}
|
||||
{% match body %}
|
||||
{% when ResetPasswordRequestBody::Form(_) %}
|
||||
<div class="panel">
|
||||
{% when ResetPasswordRequestBody::Unavailable %}
|
||||
<div class="panel middle"/>
|
||||
{% endmatch %}
|
||||
<h1>Reset your password</h1>
|
||||
{% match body %}
|
||||
{% when ResetPasswordRequestBody::Form(form) %}
|
||||
<p>
|
||||
To reset your password, enter your email below. If your Matrix account has an associated email address,
|
||||
you will receive an email with a link to reset your password.
|
||||
</p>
|
||||
<p>
|
||||
If your Matrix account does not have an associated email address, contact your homeserver's administrator
|
||||
to reset your password.
|
||||
</p>
|
||||
{{ form }}
|
||||
{% when ResetPasswordRequestBody::Unavailable %}
|
||||
<p>
|
||||
To reset your password, contact your homeserver's administrator.
|
||||
</p>
|
||||
{% endmatch %}
|
||||
</div>
|
||||
{%- endblock -%}
|
||||
@@ -0,0 +1,36 @@
|
||||
{% extends "_layout.html.j2" %}
|
||||
|
||||
{%- block title -%}
|
||||
Reset your password
|
||||
{%- endblock -%}
|
||||
|
||||
{%- block content -%}
|
||||
<div class="panel narrow">
|
||||
<h1>Reset your password</h1>
|
||||
{% match body %}
|
||||
{% when ResetPasswordValidateBody::ValidationPending { session_id, client_secret, validation_error } %}
|
||||
<p>
|
||||
Check your inbox for the validation email. If you do not receive the email:
|
||||
<ul>
|
||||
<li>Check your spam filter.</li>
|
||||
<li>Your Matrix account may not be associated with an email address. Contact your homeserver's
|
||||
administrator for assistance.</li>
|
||||
</ul>
|
||||
</p>
|
||||
{% if validation_error %}
|
||||
<small class="error">Validation failed. Have you clicked the link in the email that was sent to you?</small>
|
||||
{% endif %}
|
||||
<form method="get" action="validate">
|
||||
<input type="hidden" name="session_id" value="{{ session_id }}">
|
||||
<input type="hidden" name="client_secret" value="{{ client_secret }}">
|
||||
<button type="submit">Continue</button>
|
||||
</form>
|
||||
{% when ResetPasswordValidateBody::ValidationSuccess { user_card, form } %}
|
||||
{{ user_card }}
|
||||
{{ form }}
|
||||
{% when ResetPasswordValidateBody::ResetSuccess { user_card } %}
|
||||
{{ user_card }}
|
||||
<p>Your password has been reset successfully.</p>
|
||||
{% endmatch %}
|
||||
</div>
|
||||
{%- endblock -%}
|
||||
Reference in New Issue
Block a user