66use anyhow:: Context as _;
77use axum:: {
88 extract:: { Path , State } ,
9- response:: IntoResponse ,
9+ response:: { Html , IntoResponse , Response } ,
1010} ;
1111use axum_extra:: TypedHeader ;
1212use chrono:: Duration ;
@@ -19,10 +19,11 @@ use mas_storage::{
1919 user:: UserEmailFilter ,
2020 BoxClock , BoxRepository , BoxRng ,
2121} ;
22+ use mas_templates:: { RegisterStepsEmailInUseContext , TemplateContext as _, Templates } ;
2223use ulid:: Ulid ;
2324
2425use super :: super :: cookie:: UserRegistrationSessions ;
25- use crate :: { views:: shared:: OptionalPostAuthAction , BoundActivityTracker } ;
26+ use crate :: { views:: shared:: OptionalPostAuthAction , BoundActivityTracker , PreferredLanguage } ;
2627
2728#[ tracing:: instrument(
2829 name = "handlers.views.register.steps.finish.get" ,
@@ -38,9 +39,11 @@ pub(crate) async fn get(
3839 user_agent : Option < TypedHeader < headers:: UserAgent > > ,
3940 State ( url_builder) : State < UrlBuilder > ,
4041 State ( homeserver) : State < BoxHomeserverConnection > ,
42+ State ( templates) : State < Templates > ,
43+ PreferredLanguage ( lang) : PreferredLanguage ,
4144 cookie_jar : CookieJar ,
4245 Path ( id) : Path < Ulid > ,
43- ) -> Result < impl IntoResponse , FancyError > {
46+ ) -> Result < Response , FancyError > {
4447 let user_agent = user_agent. map ( |ua| UserAgent :: parse ( ua. as_str ( ) . to_owned ( ) ) ) ;
4548 let registration = repo
4649 . user_registration ( )
@@ -60,7 +63,8 @@ pub(crate) async fn get(
6063 return Ok ( (
6164 cookie_jar,
6265 OptionalPostAuthAction :: from ( post_auth_action) . go_next ( & url_builder) ,
63- ) ) ;
66+ )
67+ . into_response ( ) ) ;
6468 }
6569
6670 // Make sure the registration session hasn't expired
@@ -117,29 +121,42 @@ pub(crate) async fn get(
117121 return Ok ( (
118122 cookie_jar,
119123 url_builder. redirect ( & mas_router:: RegisterVerifyEmail :: new ( id) ) ,
120- ) ) ;
124+ )
125+ . into_response ( ) ) ;
121126 }
122127
123128 // Check that the email address isn't already used
129+ // It is important to do that here, as we we're not checking during the
130+ // registration, because we don't want to disclose whether an email is
131+ // already being used or not before we verified it
124132 if repo
125133 . user_email ( )
126134 . count ( UserEmailFilter :: new ( ) . for_email ( & email_authentication. email ) )
127135 . await ?
128136 > 0
129137 {
130- // XXX: this could have a better error message, but as this is unlikely to
131- // happen, we're fine with a vague message for now
132- return Err ( FancyError :: from ( anyhow:: anyhow!(
133- "Email address is already used"
134- ) ) ) ;
138+ let action = registration
139+ . post_auth_action
140+ . map ( serde_json:: from_value)
141+ . transpose ( ) ?;
142+
143+ let ctx = RegisterStepsEmailInUseContext :: new ( email_authentication. email , action)
144+ . with_language ( lang) ;
145+
146+ return Ok ( (
147+ cookie_jar,
148+ Html ( templates. render_register_steps_email_in_use ( & ctx) ?) ,
149+ )
150+ . into_response ( ) ) ;
135151 }
136152
137153 // Check that the display name is set
138154 if registration. display_name . is_none ( ) {
139155 return Ok ( (
140156 cookie_jar,
141157 url_builder. redirect ( & mas_router:: RegisterDisplayName :: new ( registration. id ) ) ,
142- ) ) ;
158+ )
159+ . into_response ( ) ) ;
143160 }
144161
145162 // Everuthing is good, let's complete the registration
@@ -215,5 +232,6 @@ pub(crate) async fn get(
215232 return Ok ( (
216233 cookie_jar,
217234 OptionalPostAuthAction :: from ( post_auth_action) . go_next ( & url_builder) ,
218- ) ) ;
235+ )
236+ . into_response ( ) ) ;
219237}
0 commit comments