Skip to main content

tuwunel_api/client/membership/
leave.rs

1use axum::extract::State;
2use futures::FutureExt;
3use ruma::api::client::membership::leave_room::v3::{Request, Response};
4use tuwunel_core::{Err, Result};
5
6use crate::{Ruma, client::admin::misc::is_notice_room};
7
8/// Leaves a room through `POST /_matrix/client/v3/rooms/{roomId}/leave`.
9///
10/// Server-notice invitations cannot be rejected, but joined recipients can leave.
11#[tracing::instrument(level = "debug", skip_all)]
12pub(crate) async fn leave_room_route(
13	State(services): State<crate::State>,
14	Ruma { body, sender_user, .. }: Ruma<Request>,
15) -> Result<Response> {
16	let state_lock = services.state.mutex.lock(&body.room_id).await;
17	let sender = sender_user
18		.as_deref()
19		.expect("user must be authenticated for this handler");
20
21	if services
22		.state_cache
23		.is_invited(sender, &body.room_id)
24		.await
25		&& is_notice_room(&services, sender, &body.room_id).await?
26	{
27		return Err!(Request(CannotLeaveServerNoticeRoom("You cannot reject this invite")));
28	}
29
30	services
31		.membership
32		.leave(sender, &body.room_id, body.reason, false, &state_lock)
33		.await?;
34
35	if services.config.delete_rooms_after_leave {
36		services
37			.delete
38			.delete_if_empty_local(&body.room_id, state_lock)
39			.boxed()
40			.await;
41	}
42
43	Ok(Response {})
44}