2021-07-14 07:07:08 +00:00
use super ::{ DEVICE_ID_LENGTH , SESSION_ID_LENGTH , TOKEN_LENGTH } ;
2022-10-05 20:34:31 +02:00
use crate ::{ api ::client_server , services , utils , Error , Result , Ruma } ;
2020-07-30 18:14:47 +02:00
use ruma ::{
api ::client ::{
2022-02-18 15:33:14 +01:00
account ::{
2022-10-25 20:47:41 +00:00
change_password , deactivate , get_3pids , get_username_availability , register ,
2022-10-30 20:36:14 +01:00
request_3pid_management_token_via_email , request_3pid_management_token_via_msisdn ,
whoami , ThirdPartyIdRemovalStatus ,
2020-07-30 18:14:47 +02:00
} ,
2022-02-18 15:33:14 +01:00
error ::ErrorKind ,
uiaa ::{ AuthFlow , AuthType , UiaaInfo } ,
2020-07-30 18:14:47 +02:00
} ,
2022-10-08 13:03:07 +02:00
events ::{ room ::message ::RoomMessageEventContent , GlobalAccountDataEventType } ,
2022-02-03 20:52:41 +02:00
push , UserId ,
2020-07-30 18:14:47 +02:00
} ;
2023-12-22 18:31:15 -05:00
use tracing ::{ info , warn } ;
2020-07-30 18:14:47 +02:00
2020-08-22 21:19:14 +02:00
use register ::RegistrationKind ;
2020-07-30 18:14:47 +02:00
2022-06-18 11:13:37 +00:00
const RANDOM_USER_ID_LENGTH : usize = 10 ;
2020-07-30 18:14:47 +02:00
2024-01-16 19:47:40 -05:00
/// # `GET /_matrix/client/v3/register/available`
2020-07-31 14:40:28 +02:00
///
/// Checks if a username is valid and available on this server.
///
2021-08-31 19:14:37 +02:00
/// Conditions for returning true:
/// - The user id is not historical
/// - The server name of the user id matches this server
/// - No user or appservice on this server already claimed this username
///
/// Note: This will not reserve the username, so the username might become invalid when trying to register
2020-10-21 21:28:02 +02:00
pub async fn get_register_available_route (
2022-12-14 13:09:10 +01:00
body : Ruma < get_username_availability ::v3 ::Request > ,
2022-02-18 15:33:14 +01:00
) -> Result < get_username_availability ::v3 ::Response > {
2020-07-30 18:14:47 +02:00
// Validate user id
2022-10-05 20:34:31 +02:00
let user_id = UserId ::parse_with_server_name (
body . username . to_lowercase ( ) ,
services ( ) . globals . server_name ( ) ,
)
. ok ( )
. filter ( | user_id | {
! user_id . is_historical ( ) & & user_id . server_name ( ) = = services ( ) . globals . server_name ( )
} )
. ok_or ( Error ::BadRequest (
ErrorKind ::InvalidUsername ,
" Username is invalid. " ,
) ) ? ;
2020-07-30 18:14:47 +02:00
// Check if username is creative enough
2022-09-06 23:15:09 +02:00
if services ( ) . users . exists ( & user_id ) ? {
2020-07-30 18:14:47 +02:00
return Err ( Error ::BadRequest (
ErrorKind ::UserInUse ,
" Desired user ID is already taken. " ,
) ) ;
}
2024-02-08 19:11:48 -05:00
if services ( )
. globals
. forbidden_usernames ( )
. is_match ( user_id . localpart ( ) )
{
return Err ( Error ::BadRequest (
ErrorKind ::Unknown ,
" Username is forbidden. " ,
) ) ;
}
2020-07-30 18:14:47 +02:00
// TODO add check for appservice namespaces
// If no if check is true we have an username that's available to be used.
2022-02-18 15:33:14 +01:00
Ok ( get_username_availability ::v3 ::Response { available : true } )
2020-07-30 18:14:47 +02:00
}
2024-02-15 20:47:12 -05:00
/// # `POST /_matrix/client/v3/register`
2020-07-31 14:40:28 +02:00
///
/// Register an account on this homeserver.
///
2024-02-15 20:47:12 -05:00
/// You can use [`GET /_matrix/client/v3/register/available`](fn.get_register_available_route.html)
2021-08-31 19:14:37 +02:00
/// to check if the user id is valid and available.
///
/// - Only works if registration is enabled
/// - If type is guest: ignores all parameters except initial_device_display_name
/// - If sender is not appservice: Requires UIAA (but we only use a dummy stage)
/// - If type is not guest and no username is given: Always fails after UIAA check
/// - Creates a new account and populates it with default account data
/// - If `inhibit_login` is false: Creates a device and returns device id and access_token
2022-12-14 13:09:10 +01:00
pub async fn register_route ( body : Ruma < register ::v3 ::Request > ) -> Result < register ::v3 ::Response > {
2024-01-24 22:29:30 -05:00
if ! services ( ) . globals . allow_registration ( ) & & ! body . from_appservice {
info! ( " Registration disabled and request not from known appservice, rejecting registration attempt for username {:?} " , body . username ) ;
2020-07-30 18:14:47 +02:00
return Err ( Error ::BadRequest (
ErrorKind ::Forbidden ,
" Registration has been disabled. " ,
) ) ;
}
2020-09-08 17:32:03 +02:00
let is_guest = body . kind = = RegistrationKind ::Guest ;
2020-08-22 21:19:14 +02:00
2023-12-21 20:44:58 -05:00
if is_guest
& & ( ! services ( ) . globals . allow_guest_registration ( )
2024-01-24 22:29:30 -05:00
| | ( services ( ) . globals . allow_registration ( )
2023-12-21 21:39:49 -05:00
& & services ( ) . globals . config . registration_token . is_some ( ) ) )
2023-12-21 20:44:58 -05:00
{
2024-01-24 22:29:30 -05:00
info! ( " Guest registration disabled / registration enabled with token configured, rejecting guest registration, initial device name: {:?} " , body . initial_device_display_name ) ;
2023-12-21 20:44:58 -05:00
return Err ( Error ::BadRequest (
ErrorKind ::GuestAccessForbidden ,
" Guest registration is disabled. " ,
) ) ;
}
2023-12-21 21:16:56 -05:00
// forbid guests from registering if there is not a real admin user yet. give generic user error.
if is_guest & & services ( ) . users . count ( ) ? < 2 {
warn! ( " Guest account attempted to register before a real admin user has been registered, rejecting registration. Guest's initial device name: {:?} " , body . initial_device_display_name ) ;
return Err ( Error ::BadRequest (
ErrorKind ::Forbidden ,
" Registration temporarily disabled. " ,
) ) ;
}
2022-06-18 11:13:37 +00:00
let user_id = match ( & body . username , is_guest ) {
( Some ( username ) , false ) = > {
2022-10-05 20:34:31 +02:00
let proposed_user_id = UserId ::parse_with_server_name (
username . to_lowercase ( ) ,
services ( ) . globals . server_name ( ) ,
)
. ok ( )
. filter ( | user_id | {
! user_id . is_historical ( )
& & user_id . server_name ( ) = = services ( ) . globals . server_name ( )
} )
. ok_or ( Error ::BadRequest (
ErrorKind ::InvalidUsername ,
" Username is invalid. " ,
) ) ? ;
2024-02-08 19:11:48 -05:00
2022-09-06 23:15:09 +02:00
if services ( ) . users . exists ( & proposed_user_id ) ? {
2022-06-18 11:13:37 +00:00
return Err ( Error ::BadRequest (
ErrorKind ::UserInUse ,
" Desired user ID is already taken. " ,
) ) ;
}
2024-02-08 19:11:48 -05:00
if services ( )
. globals
. forbidden_usernames ( )
. is_match ( proposed_user_id . localpart ( ) )
{
return Err ( Error ::BadRequest (
ErrorKind ::Unknown ,
" Username is forbidden. " ,
) ) ;
}
2022-06-18 11:13:37 +00:00
proposed_user_id
2020-08-22 21:19:14 +02:00
}
2022-06-18 11:13:37 +00:00
_ = > loop {
let proposed_user_id = UserId ::parse_with_server_name (
utils ::random_string ( RANDOM_USER_ID_LENGTH ) . to_lowercase ( ) ,
2022-09-06 23:15:09 +02:00
services ( ) . globals . server_name ( ) ,
2022-06-18 11:13:37 +00:00
)
. unwrap ( ) ;
2022-09-06 23:15:09 +02:00
if ! services ( ) . users . exists ( & proposed_user_id ) ? {
2022-06-18 11:13:37 +00:00
break proposed_user_id ;
}
} ,
} ;
2020-07-30 18:14:47 +02:00
// UIAA
2024-01-24 22:29:30 -05:00
let mut uiaainfo ;
let skip_auth ;
if services ( ) . globals . config . registration_token . is_some ( ) {
// Registration token required
uiaainfo = UiaaInfo {
flows : vec ! [ AuthFlow {
stages : vec ! [ AuthType ::RegistrationToken ] ,
} ] ,
completed : Vec ::new ( ) ,
params : Default ::default ( ) ,
session : None ,
auth_error : None ,
} ;
skip_auth = body . from_appservice ;
} else {
// No registration token necessary, but clients must still go through the flow
uiaainfo = UiaaInfo {
flows : vec ! [ AuthFlow {
stages : vec ! [ AuthType ::Dummy ] ,
} ] ,
completed : Vec ::new ( ) ,
params : Default ::default ( ) ,
session : None ,
auth_error : None ,
} ;
skip_auth = body . from_appservice | | is_guest ;
}
2020-07-30 18:14:47 +02:00
2024-01-24 22:29:30 -05:00
if ! skip_auth {
2020-12-08 10:33:44 +01:00
if let Some ( auth ) = & body . auth {
2022-09-06 23:15:09 +02:00
let ( worked , uiaainfo ) = services ( ) . uiaa . try_auth (
& UserId ::parse_with_server_name ( " " , services ( ) . globals . server_name ( ) )
2021-05-04 19:03:18 +02:00
. expect ( " we know this is valid " ) ,
" " . into ( ) ,
auth ,
& uiaainfo ,
) ? ;
2020-12-08 10:33:44 +01:00
if ! worked {
return Err ( Error ::Uiaa ( uiaainfo ) ) ;
}
// Success!
2021-07-14 12:31:38 +02:00
} else if let Some ( json ) = body . json_body {
uiaainfo . session = Some ( utils ::random_string ( SESSION_ID_LENGTH ) ) ;
2022-09-06 23:15:09 +02:00
services ( ) . uiaa . create (
& UserId ::parse_with_server_name ( " " , services ( ) . globals . server_name ( ) )
2021-07-14 12:31:38 +02:00
. expect ( " we know this is valid " ) ,
" " . into ( ) ,
& uiaainfo ,
& json ,
) ? ;
return Err ( Error ::Uiaa ( uiaainfo ) ) ;
2020-12-08 10:33:44 +01:00
} else {
2021-07-14 12:31:38 +02:00
return Err ( Error ::BadRequest ( ErrorKind ::NotJson , " Not json. " ) ) ;
2020-07-30 18:14:47 +02:00
}
}
2020-08-22 21:19:14 +02:00
let password = if is_guest {
None
} else {
2021-05-30 21:55:43 +02:00
body . password . as_deref ( )
} ;
2020-07-30 18:14:47 +02:00
// Create user
2022-09-06 23:15:09 +02:00
services ( ) . users . create ( & user_id , password ) ? ;
2020-07-30 18:14:47 +02:00
2021-08-31 19:14:37 +02:00
// Default to pretty displayname
2022-06-23 06:58:34 +00:00
let mut displayname = user_id . localpart ( ) . to_owned ( ) ;
// If enabled append lightning bolt to display name (default true)
if services ( ) . globals . enable_lightning_bolt ( ) {
displayname . push_str ( " ⚡️ " ) ;
}
2022-10-05 20:34:31 +02:00
services ( )
. users
2024-01-14 01:42:37 -05:00
. set_displayname ( & user_id , Some ( displayname . clone ( ) ) )
. await ? ;
2021-08-10 05:43:44 +00:00
2021-08-31 19:14:37 +02:00
// Initial account data
2022-09-06 23:15:09 +02:00
services ( ) . account_data . update (
2020-07-30 20:49:29 +02:00
None ,
& user_id ,
2022-04-06 21:31:29 +02:00
GlobalAccountDataEventType ::PushRules . to_string ( ) . into ( ) ,
2022-10-05 15:33:57 +02:00
& serde_json ::to_value ( ruma ::events ::push_rules ::PushRulesEvent {
2020-07-30 20:49:29 +02:00
content : ruma ::events ::push_rules ::PushRulesEventContent {
2021-04-05 21:25:10 +02:00
global : push ::Ruleset ::server_default ( & user_id ) ,
2020-07-30 20:49:29 +02:00
} ,
2022-10-05 20:34:31 +02:00
} )
. expect ( " to json always works " ) ,
2020-07-30 20:49:29 +02:00
) ? ;
2021-08-31 19:14:37 +02:00
// Inhibit login does not work for guests
2020-08-22 21:19:14 +02:00
if ! is_guest & & body . inhibit_login {
2022-02-18 15:33:14 +01:00
return Ok ( register ::v3 ::Response {
2020-07-30 20:49:29 +02:00
access_token : None ,
user_id ,
device_id : None ,
2022-10-09 17:25:06 +02:00
refresh_token : None ,
expires_in : None ,
2022-01-22 16:58:32 +01:00
} ) ;
2020-07-30 20:49:29 +02:00
}
2020-07-30 18:14:47 +02:00
// Generate new device id if the user didn't specify one
2020-08-22 21:19:14 +02:00
let device_id = if is_guest {
None
} else {
body . device_id . clone ( )
}
. unwrap_or_else ( | | utils ::random_string ( DEVICE_ID_LENGTH ) . into ( ) ) ;
2020-07-30 18:14:47 +02:00
// Generate new token for the device
let token = utils ::random_string ( TOKEN_LENGTH ) ;
2021-08-31 19:14:37 +02:00
// Create device for this account
2022-09-06 23:15:09 +02:00
services ( ) . users . create_device (
2020-07-30 18:14:47 +02:00
& user_id ,
& device_id ,
& token ,
body . initial_device_display_name . clone ( ) ,
) ? ;
2023-12-21 20:46:24 -05:00
info! ( " New user \" {} \" registered on this server. " , user_id ) ;
// log in conduit admin channel if a non-guest user registered
2023-08-09 18:27:30 +02:00
if ! body . from_appservice & & ! is_guest {
services ( )
. admin
. send_message ( RoomMessageEventContent ::notice_plain ( format! (
2023-12-21 20:46:24 -05:00
" New user \" {user_id} \" registered on this server. "
2023-08-09 18:27:30 +02:00
) ) ) ;
}
2020-10-05 22:19:22 +02:00
2023-12-21 20:46:24 -05:00
// log in conduit admin channel if a guest registered
if ! body . from_appservice & & is_guest {
services ( )
. admin
. send_message ( RoomMessageEventContent ::notice_plain ( format! (
" Guest user \" {user_id} \" with device display name `{:?}` registered on this server. " ,
body . initial_device_display_name
) ) ) ;
}
// If this is the first real user, grant them admin privileges except for guest users
2022-02-03 20:52:41 +02:00
// Note: the server user, @conduit:servername, is generated first
2023-12-21 20:46:24 -05:00
if services ( ) . users . count ( ) ? = = 2 & & ! is_guest {
2022-10-05 20:34:31 +02:00
services ( )
. admin
. make_user_admin ( & user_id , displayname )
. await ? ;
2020-10-23 14:35:41 +02:00
2022-02-03 20:52:41 +02:00
warn! ( " Granting {} admin privileges as the first user " , user_id ) ;
2020-10-05 22:19:22 +02:00
}
2022-02-18 15:33:14 +01:00
Ok ( register ::v3 ::Response {
2020-07-30 18:14:47 +02:00
access_token : Some ( token ) ,
user_id ,
device_id : Some ( device_id ) ,
2022-10-09 17:25:06 +02:00
refresh_token : None ,
expires_in : None ,
2022-01-22 16:58:32 +01:00
} )
2020-07-30 18:14:47 +02:00
}
2020-07-31 14:40:28 +02:00
/// # `POST /_matrix/client/r0/account/password`
///
/// Changes the password of this account.
///
2021-08-31 19:14:37 +02:00
/// - Requires UIAA to verify user password
/// - Changes the password of the sender user
/// - The password hash is calculated using argon2 with 32 character salt, the plain password is
/// not saved
///
/// If logout_devices is true it does the following for each device except the sender device:
/// - Invalidates access token
/// - Deletes device metadata (device id, device display name, last seen ip, last seen ts)
/// - Forgets to-device events
/// - Triggers device list updates
2020-10-21 21:28:02 +02:00
pub async fn change_password_route (
2022-12-14 13:09:10 +01:00
body : Ruma < change_password ::v3 ::Request > ,
2022-02-18 15:33:14 +01:00
) -> Result < change_password ::v3 ::Response > {
2020-10-18 20:33:12 +02:00
let sender_user = body . sender_user . as_ref ( ) . expect ( " user is authenticated " ) ;
let sender_device = body . sender_device . as_ref ( ) . expect ( " user is authenticated " ) ;
2020-07-30 18:14:47 +02:00
let mut uiaainfo = UiaaInfo {
flows : vec ! [ AuthFlow {
2021-10-13 10:16:45 +02:00
stages : vec ! [ AuthType ::Password ] ,
2020-07-30 18:14:47 +02:00
} ] ,
completed : Vec ::new ( ) ,
params : Default ::default ( ) ,
session : None ,
auth_error : None ,
} ;
if let Some ( auth ) = & body . auth {
2022-10-05 20:34:31 +02:00
let ( worked , uiaainfo ) =
services ( )
. uiaa
. try_auth ( sender_user , sender_device , auth , & uiaainfo ) ? ;
2020-07-30 18:14:47 +02:00
if ! worked {
return Err ( Error ::Uiaa ( uiaainfo ) ) ;
}
// Success!
2021-07-14 12:31:38 +02:00
} else if let Some ( json ) = body . json_body {
uiaainfo . session = Some ( utils ::random_string ( SESSION_ID_LENGTH ) ) ;
2022-10-05 20:34:31 +02:00
services ( )
. uiaa
2021-09-13 19:45:56 +02:00
. create ( sender_user , sender_device , & uiaainfo , & json ) ? ;
2021-07-14 12:31:38 +02:00
return Err ( Error ::Uiaa ( uiaainfo ) ) ;
2020-07-30 18:14:47 +02:00
} else {
2021-07-14 12:31:38 +02:00
return Err ( Error ::BadRequest ( ErrorKind ::NotJson , " Not json. " ) ) ;
2020-07-30 18:14:47 +02:00
}
2022-10-05 20:34:31 +02:00
services ( )
. users
2021-09-13 19:45:56 +02:00
. set_password ( sender_user , Some ( & body . new_password ) ) ? ;
2020-07-30 18:14:47 +02:00
2021-01-16 14:48:24 -07:00
if body . logout_devices {
// Logout all devices except the current one
2022-09-06 23:15:09 +02:00
for id in services ( )
2021-01-16 14:48:24 -07:00
. users
2021-09-13 19:45:56 +02:00
. all_device_ids ( sender_user )
2021-01-16 14:48:24 -07:00
. filter_map ( | id | id . ok ( ) )
. filter ( | id | id ! = sender_device )
{
2022-09-06 23:15:09 +02:00
services ( ) . users . remove_device ( sender_user , & id ) ? ;
2021-01-16 14:48:24 -07:00
}
2020-07-30 18:14:47 +02:00
}
2022-02-22 00:02:01 +01:00
info! ( " User {} changed their password. " , sender_user ) ;
2022-10-05 20:34:31 +02:00
services ( )
. admin
2022-02-22 00:02:01 +01:00
. send_message ( RoomMessageEventContent ::notice_plain ( format! (
2022-12-21 10:42:12 +01:00
" User {sender_user} changed their password. "
2022-02-22 00:02:01 +01:00
) ) ) ;
2022-02-18 15:33:14 +01:00
Ok ( change_password ::v3 ::Response { } )
2020-07-30 18:14:47 +02:00
}
2020-07-31 14:40:28 +02:00
/// # `GET _matrix/client/r0/account/whoami`
///
2021-08-31 19:14:37 +02:00
/// Get user_id of the sender user.
2020-07-31 14:40:28 +02:00
///
2021-08-31 19:14:37 +02:00
/// Note: Also works for Application Services
2022-10-05 20:34:31 +02:00
pub async fn whoami_route ( body : Ruma < whoami ::v3 ::Request > ) -> Result < whoami ::v3 ::Response > {
2020-10-18 20:33:12 +02:00
let sender_user = body . sender_user . as_ref ( ) . expect ( " user is authenticated " ) ;
2022-03-05 10:16:21 +08:00
let device_id = body . sender_device . as_ref ( ) . cloned ( ) ;
2022-04-06 18:49:46 +02:00
2022-02-18 15:33:14 +01:00
Ok ( whoami ::v3 ::Response {
2020-10-18 20:33:12 +02:00
user_id : sender_user . clone ( ) ,
2022-03-05 10:16:21 +08:00
device_id ,
2022-10-15 13:17:58 +02:00
is_guest : services ( ) . users . is_deactivated ( sender_user ) ? & & ! body . from_appservice ,
2022-01-22 16:58:32 +01:00
} )
2020-07-30 18:14:47 +02:00
}
2020-07-31 14:40:28 +02:00
/// # `POST /_matrix/client/r0/account/deactivate`
///
2021-08-31 19:14:37 +02:00
/// Deactivate sender user account.
2020-07-31 14:40:28 +02:00
///
/// - Leaves all rooms and rejects all invitations
/// - Invalidates all access tokens
2021-08-31 19:14:37 +02:00
/// - Deletes all device metadata (device id, device display name, last seen ip, last seen ts)
/// - Forgets all to-device events
/// - Triggers device list updates
2020-07-31 14:40:28 +02:00
/// - Removes ability to log in again
2020-09-14 20:23:19 +02:00
pub async fn deactivate_route (
2022-12-14 13:09:10 +01:00
body : Ruma < deactivate ::v3 ::Request > ,
2022-02-18 15:33:14 +01:00
) -> Result < deactivate ::v3 ::Response > {
2020-10-18 20:33:12 +02:00
let sender_user = body . sender_user . as_ref ( ) . expect ( " user is authenticated " ) ;
let sender_device = body . sender_device . as_ref ( ) . expect ( " user is authenticated " ) ;
2020-07-30 18:14:47 +02:00
let mut uiaainfo = UiaaInfo {
flows : vec ! [ AuthFlow {
2021-10-13 10:16:45 +02:00
stages : vec ! [ AuthType ::Password ] ,
2020-07-30 18:14:47 +02:00
} ] ,
completed : Vec ::new ( ) ,
params : Default ::default ( ) ,
session : None ,
auth_error : None ,
} ;
if let Some ( auth ) = & body . auth {
2022-10-05 20:34:31 +02:00
let ( worked , uiaainfo ) =
services ( )
. uiaa
. try_auth ( sender_user , sender_device , auth , & uiaainfo ) ? ;
2020-07-30 18:14:47 +02:00
if ! worked {
return Err ( Error ::Uiaa ( uiaainfo ) ) ;
}
// Success!
2021-07-14 12:31:38 +02:00
} else if let Some ( json ) = body . json_body {
uiaainfo . session = Some ( utils ::random_string ( SESSION_ID_LENGTH ) ) ;
2022-10-05 20:34:31 +02:00
services ( )
. uiaa
2021-09-13 19:45:56 +02:00
. create ( sender_user , sender_device , & uiaainfo , & json ) ? ;
2021-07-14 12:31:38 +02:00
return Err ( Error ::Uiaa ( uiaainfo ) ) ;
2020-07-30 18:14:47 +02:00
} else {
2021-07-14 12:31:38 +02:00
return Err ( Error ::BadRequest ( ErrorKind ::NotJson , " Not json. " ) ) ;
2020-07-30 18:14:47 +02:00
}
2022-04-02 14:00:19 +02:00
// Make the user leave all rooms before deactivation
2022-10-10 14:09:11 +02:00
client_server ::leave_all_rooms ( sender_user ) . await ? ;
2020-07-30 18:14:47 +02:00
// Remove devices and mark account as deactivated
2022-09-06 23:15:09 +02:00
services ( ) . users . deactivate_account ( sender_user ) ? ;
2020-07-30 18:14:47 +02:00
2022-02-22 00:02:01 +01:00
info! ( " User {} deactivated their account. " , sender_user ) ;
2022-10-05 20:34:31 +02:00
services ( )
. admin
2022-02-22 00:02:01 +01:00
. send_message ( RoomMessageEventContent ::notice_plain ( format! (
2022-12-21 10:42:12 +01:00
" User {sender_user} deactivated their account. "
2022-02-22 00:02:01 +01:00
) ) ) ;
2020-11-15 12:17:21 +01:00
2022-02-18 15:33:14 +01:00
Ok ( deactivate ::v3 ::Response {
2020-07-30 18:14:47 +02:00
id_server_unbind_result : ThirdPartyIdRemovalStatus ::NoSupport ,
2022-01-22 16:58:32 +01:00
} )
2020-07-30 18:14:47 +02:00
}
2021-01-26 21:54:35 -05:00
2022-10-25 20:47:41 +00:00
/// # `GET _matrix/client/v3/account/3pid`
2021-08-09 12:29:35 -07:00
///
/// Get a list of third party identifiers associated with this account.
2021-08-31 19:14:37 +02:00
///
/// - Currently always returns empty list
2022-02-18 15:33:14 +01:00
pub async fn third_party_route (
body : Ruma < get_3pids ::v3 ::Request > ,
) -> Result < get_3pids ::v3 ::Response > {
2021-08-17 16:06:09 +02:00
let _sender_user = body . sender_user . as_ref ( ) . expect ( " user is authenticated " ) ;
2021-01-26 21:54:35 -05:00
2022-02-18 15:33:14 +01:00
Ok ( get_3pids ::v3 ::Response ::new ( Vec ::new ( ) ) )
2021-01-26 21:54:35 -05:00
}
2022-10-25 20:47:41 +00:00
/// # `POST /_matrix/client/v3/account/3pid/email/requestToken`
///
/// "This API should be used to request validation tokens when adding an email address to an account"
///
/// - 403 signals that The homeserver does not allow the third party identifier as a contact option.
pub async fn request_3pid_management_token_via_email_route (
2022-12-14 13:09:10 +01:00
_body : Ruma < request_3pid_management_token_via_email ::v3 ::Request > ,
2022-10-25 20:47:41 +00:00
) -> Result < request_3pid_management_token_via_email ::v3 ::Response > {
Err ( Error ::BadRequest (
ErrorKind ::ThreepidDenied ,
" Third party identifier is not allowed " ,
) )
}
/// # `POST /_matrix/client/v3/account/3pid/msisdn/requestToken`
///
/// "This API should be used to request validation tokens when adding an phone number to an account"
///
/// - 403 signals that The homeserver does not allow the third party identifier as a contact option.
pub async fn request_3pid_management_token_via_msisdn_route (
2022-12-14 13:09:10 +01:00
_body : Ruma < request_3pid_management_token_via_msisdn ::v3 ::Request > ,
2022-10-25 20:47:41 +00:00
) -> Result < request_3pid_management_token_via_msisdn ::v3 ::Response > {
Err ( Error ::BadRequest (
ErrorKind ::ThreepidDenied ,
" Third party identifier is not allowed " ,
) )
}