diff --git a/lang/de.mo b/lang/de.mo index 4c9055b5..e7568c8a 100644 Binary files a/lang/de.mo and b/lang/de.mo differ diff --git a/lang/de.po b/lang/de.po index 6e56a4cf..8a249525 100644 --- a/lang/de.po +++ b/lang/de.po @@ -29,6 +29,9 @@ msgstr "Benutze den Link in der Email für den Login bei" msgid "Alternatively, enter the code from the email to continue in this browser tab:" msgstr "Alternativ gebe in diesem Browsertab den in der Email stehenden Code ein:" +msgid "The code you entered was incorrect." +msgstr "Der eingegebene Code war falsch." + msgid "The request is invalid, and could not be completed." msgstr "Dieser Seitenaufruf ist fehlerhaft, und wir können ihn nicht beenden." diff --git a/lang/en.mo b/lang/en.mo index 31c18156..0ca68f1d 100644 Binary files a/lang/en.mo and b/lang/en.mo differ diff --git a/lang/en.po b/lang/en.po index daf4c63f..957dd9a1 100644 --- a/lang/en.po +++ b/lang/en.po @@ -29,6 +29,9 @@ msgstr "Use the link in that email to login to" msgid "Alternatively, enter the code from the email to continue in this browser tab:" msgstr "Alternatively, enter the code from the email to continue in this browser tab:" +msgid "The code you entered was incorrect." +msgstr "The code you entered was incorrect." + msgid "The request is invalid, and could not be completed." msgstr "The request is invalid, and could not be completed." diff --git a/lang/fr.mo b/lang/fr.mo index cfc7e53f..07c1661a 100644 Binary files a/lang/fr.mo and b/lang/fr.mo differ diff --git a/lang/fr.po b/lang/fr.po index 08f583ab..504f0388 100644 --- a/lang/fr.po +++ b/lang/fr.po @@ -29,6 +29,9 @@ msgstr "Utilisez le lien contenu dans cet e-mail pour vous connecter à" msgid "Alternatively, enter the code from the email to continue in this browser tab:" msgstr "Vous pouvez également saisir le code figurant dans l'e-mail pour continuer dans cet onglet du navigateur :" +msgid "The code you entered was incorrect." +msgstr "Le code saisi était incorrect." + msgid "The request is invalid, and could not be completed." msgstr "La demande n'est pas valide et n'a pas pu être traitée." diff --git a/lang/fr_CA.mo b/lang/fr_CA.mo index 046f83a3..6f7a374d 100644 Binary files a/lang/fr_CA.mo and b/lang/fr_CA.mo differ diff --git a/lang/fr_CA.po b/lang/fr_CA.po index e00b3227..679dc289 100644 --- a/lang/fr_CA.po +++ b/lang/fr_CA.po @@ -29,6 +29,9 @@ msgstr "Utilisez le lien contenu dans ce courriel pour vous connecter à" msgid "Alternatively, enter the code from the email to continue in this browser tab:" msgstr "Vous pouvez également saisir le code figurant dans l'e-mail pour continuer dans cet onglet du navigateur :" +msgid "The code you entered was incorrect." +msgstr "Le code saisi était incorrect." + msgid "The request is invalid, and could not be completed." msgstr "La demande n'est pas valide et n'a pas pu être traitée." diff --git a/lang/nl.mo b/lang/nl.mo index f6ca5b29..6c2a09e2 100644 Binary files a/lang/nl.mo and b/lang/nl.mo differ diff --git a/lang/nl.po b/lang/nl.po index 79498c07..519503d1 100644 --- a/lang/nl.po +++ b/lang/nl.po @@ -29,6 +29,9 @@ msgstr "Gebruik de link in die email om in te loggen op" msgid "Alternatively, enter the code from the email to continue in this browser tab:" msgstr "Als alternatief kunt u ook de code uit de email invoeren om in deze browser tab verder te gaan:" +msgid "The code you entered was incorrect." +msgstr "De ingevoerde code was incorrect." + msgid "The request is invalid, and could not be completed." msgstr "De aanvraag is ongeldig, en kon niet worden verwerkt." diff --git a/res/static/style.css b/res/static/style.css index 4fc5cf0b..06b7127e 100644 --- a/res/static/style.css +++ b/res/static/style.css @@ -58,3 +58,6 @@ hr { aside p, aside .entry button, aside .entry input { font-size: 0.9em; } +aside .error { + color: #f00; +} diff --git a/src/bridges/email.rs b/src/bridges/email.rs index 932e7b67..56d3a998 100644 --- a/src/bridges/email.rs +++ b/src/bridges/email.rs @@ -1,9 +1,12 @@ use crate::agents::mailer::SendMail; use crate::bridges::{complete_auth, AuthContext, BridgeData}; +use crate::config::Config; use crate::crypto::random_zbase32; use crate::error::BrokerError; use crate::metrics; -use crate::web::{html_response, json_response, Context, HandlerResult}; +use crate::web::{html_response, json_response, Context, HandlerResult, Response}; +use gettext::Catalog; +use http::StatusCode; use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; use serde::{Deserialize, Serialize}; use serde_json::json; @@ -39,13 +42,7 @@ pub async fn auth(mut ctx: AuthContext) -> HandlerResult { utf8_percent_encode(&code, QUERY_ESCAPE) ); - let display_origin = ctx - .return_params - .as_ref() - .expect("email::request called without redirect_uri set") - .redirect_uri - .origin() - .unicode_serialization(); + let display_origin = ctx.display_origin(); let catalog = ctx.catalog(); let subject = format!( @@ -103,26 +100,13 @@ pub async fn auth(mut ctx: AuthContext) -> HandlerResult { "session": &ctx.session_id, }))) } else { - let catalog = ctx.catalog(); - Ok(html_response(ctx.app.templates.confirm_email.render(&[ - ("display_origin", display_origin.as_str()), - ("session_id", &ctx.session_id), - ("title", catalog.gettext("Confirm your address")), - ( - "explanation", - catalog.gettext("We've sent you an email to confirm your address."), - ), - ( - "use", - catalog.gettext("Use the link in that email to login to"), - ), - ( - "alternate", - catalog.gettext( - "Alternatively, enter the code from the email to continue in this browser tab:", - ), - ), - ]))) + Ok(render_form( + &ctx.app, + ctx.catalog(), + &ctx.session_id, + &display_origin, + None, + )) } } @@ -143,7 +127,21 @@ pub async fn confirmation(ctx: &mut Context) -> HandlerResult { if code != bridge_data.code { metrics::AUTH_EMAIL_CODE_INCORRECT.inc(); - return Err(BrokerError::ProviderInput("incorrect code".to_owned())); + let mut res = if ctx.want_json { + json_response(&json!({ + "result": "incorrect_code", + })) + } else { + render_form( + &ctx.app, + ctx.catalog(), + &ctx.session_id, + &ctx.display_origin(), + Some("The code you entered was incorrect."), + ) + }; + *res.status_mut() = StatusCode::FORBIDDEN; + return Ok(res); } if !ctx.app.uncounted_emails.contains(&data.email_addr) { @@ -152,3 +150,35 @@ pub async fn confirmation(ctx: &mut Context) -> HandlerResult { complete_auth(ctx, data).await } + +fn render_form( + app: &Config, + catalog: &Catalog, + session_id: &str, + display_origin: &str, + error: Option<&str>, +) -> Response { + html_response(app.templates.confirm_email.render(&[ + ("display_origin", display_origin), + ("session_id", session_id), + ("title", catalog.gettext("Confirm your address")), + ( + "explanation", + catalog.gettext("We've sent you an email to confirm your address."), + ), + ( + "use", + catalog.gettext("Use the link in that email to login to"), + ), + ( + "alternate", + catalog.gettext( + "Alternatively, enter the code from the email to continue in this browser tab:", + ), + ), + ( + "error", + error.map(|msg| catalog.gettext(msg)).unwrap_or_default(), + ), + ])) +} diff --git a/src/web.rs b/src/web.rs index 7b149849..88c46c33 100644 --- a/src/web.rs +++ b/src/web.rs @@ -148,6 +148,16 @@ impl RequestData { pub fn form_params(&self) -> HashMap { parse_form_encoded(&self.body) } + + /// Unicode serialization of the origin for display. + pub fn display_origin(&self) -> String { + self.return_params + .as_ref() + .expect("display_origin called without redirect_uri set") + .redirect_uri + .origin() + .unicode_serialization() + } } impl Context { diff --git a/tmpl/confirm_email.mustache b/tmpl/confirm_email.mustache index 70482c13..df5cb1f8 100644 --- a/tmpl/confirm_email.mustache +++ b/tmpl/confirm_email.mustache @@ -29,6 +29,11 @@ + {{# error }} +

+ {{ error }} +

+ {{/ error }}