Skip to main content

tuwunel_api/client/device/
delete_devices.rs

1use axum::extract::State;
2use futures::StreamExt;
3use ruma::api::client::device::delete_devices::{self, v3::Response};
4use tuwunel_core::{
5	Result, debug,
6	utils::stream::{IterStream, automatic_width},
7};
8
9use crate::{Ruma, router::auth_uiaa};
10
11/// # `POST /_matrix/client/v3/delete_devices`
12///
13/// Deletes the given list of devices.
14///
15/// - Requires UIAA to verify user password unless from an appservice with
16///   MSC4190 enabled.
17///
18/// For each device:
19/// - Invalidates access token
20/// - Deletes device metadata (device id, device display name, last seen ip,
21///   last seen ts)
22/// - Forgets to-device events
23/// - Triggers device list updates
24pub(crate) async fn delete_devices_route(
25	State(services): State<crate::State>,
26	body: Ruma<delete_devices::v3::Request>,
27) -> Result<Response> {
28	let appservice = body.appservice_info.as_ref();
29
30	if appservice.is_some_and(|appservice| appservice.registration.device_management) {
31		let sender_user = body.sender_user();
32		debug!(
33			"Skipping UIAA for {sender_user} as this is from an appservice and MSC4190 is \
34			 enabled"
35		);
36		body.devices
37			.iter()
38			.stream()
39			.for_each_concurrent(automatic_width(), |device_id| {
40				services
41					.users
42					.remove_device(sender_user, device_id)
43			})
44			.await;
45
46		return Ok(Response {});
47	}
48
49	let ref sender_user = auth_uiaa(&services, &body).await?;
50
51	body.devices
52		.iter()
53		.stream()
54		.for_each_concurrent(automatic_width(), |device_id| {
55			services
56				.users
57				.remove_device(sender_user, device_id)
58		})
59		.await;
60
61	Ok(Response {})
62}