6
6
use anyhow:: Context as _;
7
7
use axum:: {
8
8
extract:: { Path , State } ,
9
- response:: IntoResponse ,
9
+ response:: { Html , IntoResponse , Response } ,
10
10
} ;
11
11
use axum_extra:: TypedHeader ;
12
12
use chrono:: Duration ;
@@ -19,10 +19,11 @@ use mas_storage::{
19
19
user:: UserEmailFilter ,
20
20
BoxClock , BoxRepository , BoxRng ,
21
21
} ;
22
+ use mas_templates:: { RegisterStepsEmailInUseContext , TemplateContext as _, Templates } ;
22
23
use ulid:: Ulid ;
23
24
24
25
use super :: super :: cookie:: UserRegistrationSessions ;
25
- use crate :: { views:: shared:: OptionalPostAuthAction , BoundActivityTracker } ;
26
+ use crate :: { views:: shared:: OptionalPostAuthAction , BoundActivityTracker , PreferredLanguage } ;
26
27
27
28
#[ tracing:: instrument(
28
29
name = "handlers.views.register.steps.finish.get" ,
@@ -38,9 +39,11 @@ pub(crate) async fn get(
38
39
user_agent : Option < TypedHeader < headers:: UserAgent > > ,
39
40
State ( url_builder) : State < UrlBuilder > ,
40
41
State ( homeserver) : State < BoxHomeserverConnection > ,
42
+ State ( templates) : State < Templates > ,
43
+ PreferredLanguage ( lang) : PreferredLanguage ,
41
44
cookie_jar : CookieJar ,
42
45
Path ( id) : Path < Ulid > ,
43
- ) -> Result < impl IntoResponse , FancyError > {
46
+ ) -> Result < Response , FancyError > {
44
47
let user_agent = user_agent. map ( |ua| UserAgent :: parse ( ua. as_str ( ) . to_owned ( ) ) ) ;
45
48
let registration = repo
46
49
. user_registration ( )
@@ -60,7 +63,8 @@ pub(crate) async fn get(
60
63
return Ok ( (
61
64
cookie_jar,
62
65
OptionalPostAuthAction :: from ( post_auth_action) . go_next ( & url_builder) ,
63
- ) ) ;
66
+ )
67
+ . into_response ( ) ) ;
64
68
}
65
69
66
70
// Make sure the registration session hasn't expired
@@ -117,29 +121,42 @@ pub(crate) async fn get(
117
121
return Ok ( (
118
122
cookie_jar,
119
123
url_builder. redirect ( & mas_router:: RegisterVerifyEmail :: new ( id) ) ,
120
- ) ) ;
124
+ )
125
+ . into_response ( ) ) ;
121
126
}
122
127
123
128
// 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
124
132
if repo
125
133
. user_email ( )
126
134
. count ( UserEmailFilter :: new ( ) . for_email ( & email_authentication. email ) )
127
135
. await ?
128
136
> 0
129
137
{
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 ( ) ) ;
135
151
}
136
152
137
153
// Check that the display name is set
138
154
if registration. display_name . is_none ( ) {
139
155
return Ok ( (
140
156
cookie_jar,
141
157
url_builder. redirect ( & mas_router:: RegisterDisplayName :: new ( registration. id ) ) ,
142
- ) ) ;
158
+ )
159
+ . into_response ( ) ) ;
143
160
}
144
161
145
162
// Everuthing is good, let's complete the registration
@@ -215,5 +232,6 @@ pub(crate) async fn get(
215
232
return Ok ( (
216
233
cookie_jar,
217
234
OptionalPostAuthAction :: from ( post_auth_action) . go_next ( & url_builder) ,
218
- ) ) ;
235
+ )
236
+ . into_response ( ) ) ;
219
237
}
0 commit comments