tuwunel_api/client/
account.rs1use axum::extract::State;
2use futures::{FutureExt, StreamExt};
3use ruma::api::client::account::{
4 ThirdPartyIdRemovalStatus, change_password, deactivate, get_3pids,
5 request_3pid_management_token_via_email, request_3pid_management_token_via_msisdn, whoami,
6};
7use tuwunel_core::{Err, Result, err, info, utils::ReadyExt};
8
9use crate::{ClientIp, Ruma, router::auth_uiaa};
10
11#[tracing::instrument(skip_all, fields(%client), name = "change_password")]
29pub(crate) async fn change_password_route(
30 State(services): State<crate::State>,
31 ClientIp(client): ClientIp,
32 body: Ruma<change_password::v3::Request>,
33) -> Result<change_password::v3::Response> {
34 let ref sender_user = auth_uiaa(&services, &body).await?;
35
36 services
37 .users
38 .set_password(sender_user, Some(&body.new_password))
39 .await?;
40
41 if body.logout_devices {
42 services
44 .users
45 .all_device_ids(sender_user)
46 .ready_filter(|&id| Some(id) != body.sender_device.as_deref())
47 .for_each(|id| services.users.remove_device(sender_user, id))
48 .await;
49 }
50
51 info!("User {sender_user} changed their password.");
52
53 if services.server.config.admin_room_notices {
54 services
55 .admin
56 .notice(&format!("User {sender_user} changed their password."))
57 .await;
58 }
59
60 Ok(change_password::v3::Response {})
61}
62
63pub(crate) async fn whoami_route(
69 State(services): State<crate::State>,
70 body: Ruma<whoami::v3::Request>,
71) -> Result<whoami::v3::Response> {
72 Ok(whoami::v3::Response {
73 user_id: body.sender_user().to_owned(),
74 device_id: body.sender_device.clone(),
75 is_guest: body.appservice_info.is_none()
76 && services
77 .users
78 .is_deactivated(body.sender_user())
79 .await
80 .map_err(|_| err!(Request(Forbidden("User does not exist."))))?,
81 })
82}
83
84#[tracing::instrument(skip_all, fields(%client), name = "deactivate")]
96pub(crate) async fn deactivate_route(
97 State(services): State<crate::State>,
98 ClientIp(client): ClientIp,
99 body: Ruma<deactivate::v3::Request>,
100) -> Result<deactivate::v3::Response> {
101 let ref sender_user = auth_uiaa(&services, &body).await?;
102
103 services
104 .deactivate
105 .full_deactivate(sender_user, body.erase)
106 .boxed()
107 .await?;
108
109 info!("User {sender_user} deactivated their account.");
110 if services.server.config.admin_room_notices {
111 services
112 .admin
113 .notice(&format!("User {sender_user} deactivated their account."))
114 .await;
115 }
116
117 Ok(deactivate::v3::Response {
118 id_server_unbind_result: ThirdPartyIdRemovalStatus::NoSupport,
119 })
120}
121
122pub(crate) async fn third_party_route(
128 body: Ruma<get_3pids::v3::Request>,
129) -> Result<get_3pids::v3::Response> {
130 let _sender_user = body
131 .sender_user
132 .as_ref()
133 .expect("user is authenticated");
134
135 Ok(get_3pids::v3::Response::new(Vec::new()))
136}
137
138pub(crate) async fn request_3pid_management_token_via_email_route(
146 _body: Ruma<request_3pid_management_token_via_email::v3::Request>,
147) -> Result<request_3pid_management_token_via_email::v3::Response> {
148 Err!(Request(ThreepidDenied("Third party identifiers are not implemented")))
149}
150
151pub(crate) async fn request_3pid_management_token_via_msisdn_route(
159 _body: Ruma<request_3pid_management_token_via_msisdn::v3::Request>,
160) -> Result<request_3pid_management_token_via_msisdn::v3::Response> {
161 Err!(Request(ThreepidDenied("Third party identifiers are not implemented")))
162}