diff --git a/src/api/client/account/threepid.rs b/src/api/client/account/threepid.rs index dea02ea2c..3be31263b 100644 --- a/src/api/client/account/threepid.rs +++ b/src/api/client/account/threepid.rs @@ -25,6 +25,10 @@ pub(crate) async fn third_party_route( let sender_user = body.identity.expect_sender_user()?; let mut threepids = vec![]; + if !services.threepid.email_requirement().may_view() { + return Ok(get_3pids::v3::Response::new(vec![])); + } + if let Some(email) = services .threepid .get_email_for_localpart(sender_user.localpart()) diff --git a/src/service/threepid/mod.rs b/src/service/threepid/mod.rs index 98d2387e7..7913980da 100644 --- a/src/service/threepid/mod.rs +++ b/src/service/threepid/mod.rs @@ -33,7 +33,9 @@ pub enum EmailRequirement { Required, /// Users may change or remove their email. Optional, - /// Users may not change their email at all. + /// Users may see their email, but may not change it. + Locked, + /// Email features are disabled. Unavailable, } @@ -43,6 +45,9 @@ pub fn may_change(&self) -> bool { matches!(self, Self::Required | Self::Optiona #[must_use] pub fn may_remove(&self) -> bool { matches!(self, Self::Optional) } + + #[must_use] + pub fn may_view(&self) -> bool { !matches!(self, Self::Unavailable) } } struct Data { @@ -91,7 +96,7 @@ pub fn email_requirement(&self) -> EmailRequirement { && matches!(oidc.profile_key_import_mode, OidcProfileKeyImportMode::OnLogin) && oidc.email_claim.is_some() { - EmailRequirement::Unavailable + EmailRequirement::Locked } else if smtp.require_email_for_registration || smtp.require_email_for_token_registration { diff --git a/src/web/pages/account/email.rs b/src/web/pages/account/email.rs index cc9b9e294..60baea17b 100644 --- a/src/web/pages/account/email.rs +++ b/src/web/pages/account/email.rs @@ -81,6 +81,10 @@ async fn route_change_email( ) -> Result { let user_id = user.expect_recent(LoginTarget::ChangeEmail)?; + if !services.threepid.email_requirement().may_change() { + return Err(WebError::Forbidden("You may not change your email address.".to_owned())); + } + let Some(form) = form else { return response!(ChangeEmail::new( context.clone(), diff --git a/src/web/pages/templates/account.html.j2 b/src/web/pages/templates/account.html.j2 index 396aadb9b..5cee286e9 100644 --- a/src/web/pages/templates/account.html.j2 +++ b/src/web/pages/templates/account.html.j2 @@ -17,14 +17,16 @@ Your account

{% endif %}
- {% if email_requirement.may_change() %} + {% if email_requirement.may_view() %}

{% if let Some(email) = email %} Your account's associated email address is {{ email }}. {% else %} Your account has no associated email address. {% endif %} - Change your email + {% if email_requirement.may_change() %} + Change your email\ + {% endif %}

{% endif %} {% if !oidc_enabled %}