Separate error page when the recovery link was already used

This commit is contained in:
Quentin Gliech
2024-06-27 13:43:03 +02:00
parent a3b8c7815b
commit af40a9f815
5 changed files with 76 additions and 3 deletions

View File

@@ -77,7 +77,13 @@ pub(crate) async fn get(
.await?
.context("Unknown session")?;
if !ticket.active(clock.now()) || session.consumed_at.is_some() {
if session.consumed_at.is_some() {
let context = EmptyContext.with_language(locale);
let rendered = templates.render_recovery_consumed(&context)?;
return Ok((cookie_jar, Html(rendered)).into_response());
}
if !ticket.active(clock.now()) {
let context = RecoveryExpiredContext::new(session)
.with_csrf(csrf_token.form_value())
.with_language(locale);
@@ -118,6 +124,7 @@ pub(crate) async fn get(
Ok((cookie_jar, Html(rendered)).into_response())
}
#[allow(clippy::too_many_lines)]
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,
@@ -152,7 +159,13 @@ pub(crate) async fn post(
.await?
.context("Unknown session")?;
if !ticket.active(clock.now()) || session.consumed_at.is_some() {
if session.consumed_at.is_some() {
let context = EmptyContext.with_language(locale);
let rendered = templates.render_recovery_consumed(&context)?;
return Ok((cookie_jar, Html(rendered)).into_response());
}
if !ticket.active(clock.now()) {
let context = RecoveryExpiredContext::new(session)
.with_csrf(csrf_token.form_value())
.with_language(locale);

View File

@@ -68,6 +68,12 @@ pub(crate) async fn get(
.into_response());
};
if recovery_session.consumed_at.is_some() {
let context = EmptyContext.with_language(locale);
let rendered = templates.render_recovery_consumed(&context)?;
return Ok((cookie_jar, Html(rendered)).into_response());
}
let context = RecoveryProgressContext::new(recovery_session)
.with_csrf(csrf_token.form_value())
.with_language(locale);
@@ -115,6 +121,12 @@ pub(crate) async fn post(
.into_response());
};
if recovery_session.consumed_at.is_some() {
let context = EmptyContext.with_language(locale);
let rendered = templates.render_recovery_consumed(&context)?;
return Ok((cookie_jar, Html(rendered)).into_response());
}
// Verify the CSRF token
let () = cookie_jar.verify_form(&clock, form)?;

View File

@@ -360,6 +360,9 @@ register_templates! {
/// Render the account recovery link expired page
pub fn render_recovery_expired(WithLanguage<WithCsrf<RecoveryExpiredContext>>) { "pages/recovery/expired.html" }
/// Render the account recovery link consumed page
pub fn render_recovery_consumed(WithLanguage<EmptyContext>) { "pages/recovery/consumed.html" }
/// Render the account recovery disabled page
pub fn render_recovery_disabled(WithLanguage<EmptyContext>) { "pages/recovery/disabled.html" }
@@ -432,6 +435,7 @@ impl Templates {
check::render_recovery_progress(self, now, rng)?;
check::render_recovery_finish(self, now, rng)?;
check::render_recovery_expired(self, now, rng)?;
check::render_recovery_consumed(self, now, rng)?;
check::render_recovery_disabled(self, now, rng)?;
check::render_reauth(self, now, rng)?;
check::render_form_post::<EmptyContext>(self, now, rng)?;

View File

@@ -0,0 +1,32 @@
{#
Copyright 2024 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
#}
{% extends "base.html" %}
{% block content %}
<header class="page-heading">
<div class="icon invalid">
{{ icon.error() }}
</div>
<div class="header">
<h1 class="title">{{ _("mas.recovery.consumed.heading") }}</h1>
<p class="text">{{ _("mas.recovery.consumed.description") }}</p>
</div>
{{ button.link_outline(text=_("action.start_over"), href="/login") }}
</header>
{% endblock content %}

View File

@@ -26,7 +26,7 @@
},
"start_over": "Start over",
"@start_over": {
"context": "pages/recovery/expired.html:38:32-54"
"context": "pages/recovery/consumed.html:30:32-54, pages/recovery/expired.html:38:32-54"
}
},
"app": {
@@ -389,6 +389,18 @@
}
},
"recovery": {
"consumed": {
"description": "To create a new password, start over and select “Forgot password”.",
"@description": {
"context": "pages/recovery/consumed.html:27:25-63",
"description": "Description on the error page shown when a user tries to use a recovery link that has already been used"
},
"heading": "The link to reset your password has already been used",
"@heading": {
"context": "pages/recovery/consumed.html:26:27-61",
"description": "Title on the error page shown when a user tries to use a recovery link that has already been used"
}
},
"disabled": {
"description": "If you have lost your credentials, please contact the administrator to recover your account.",
"@description": {