refactor: Use more consistent terminology for email validation pages

This commit is contained in:
Ginger
2026-05-06 14:38:06 -04:00
parent d0de182afe
commit 1f1fc5eb9f
12 changed files with 168 additions and 165 deletions
+1 -1
View File
@@ -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::{
+17 -17
View File
@@ -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(
+27 -27
View File
@@ -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))
}
+10 -8
View File
@@ -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;
+26 -24
View File
@@ -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 -%}
+1
View File
@@ -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.
+17 -21
View File
@@ -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 -%}