diff --git a/src/client_server.rs b/src/client_server.rs
index a2045d8f..67480823 100644
--- a/src/client_server.rs
+++ b/src/client_server.rs
@@ -29,7 +29,7 @@ use ruma_client_api::{
push::{self, get_pushrules_all, set_pushrule, set_pushrule_enabled},
read_marker::set_read_marker,
room::create_room,
- session::{get_login_types, login},
+ session::{get_login_types, login, logout},
state::{
create_state_event_for_empty_key, create_state_event_for_key, get_state_events,
get_state_events_for_empty_key, get_state_events_for_key,
@@ -311,6 +311,19 @@ pub fn login_route(
}))
}
+#[post("/_matrix/client/r0/logout", data = "
")]
+pub fn logout_route(
+ db: State<'_, Database>,
+ body: Ruma,
+) -> MatrixResult {
+ let user_id = body.user_id.as_ref().expect("user is authenticated");
+ let device_id = body.device_id.as_ref().expect("user is authenticated");
+
+ db.users.remove_device(&user_id, &device_id).unwrap();
+
+ MatrixResult(Ok(logout::Response))
+}
+
#[get("/_matrix/client/r0/capabilities")]
pub fn get_capabilities_route() -> MatrixResult {
// TODO
diff --git a/src/database/users.rs b/src/database/users.rs
index bf1f2145..81a7bb8a 100644
--- a/src/database/users.rs
+++ b/src/database/users.rs
@@ -123,6 +123,37 @@ impl Users {
Ok(())
}
+ /// Removes a device from a user
+ pub fn remove_device(&self, user_id: &UserId, device_id: &DeviceId) -> Result<()> {
+ let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
+ userdeviceid.push(0xff);
+ userdeviceid.extend_from_slice(device_id.as_bytes());
+
+ // Remove device keys
+ self.userdeviceid_devicekeys.remove(&userdeviceid)?;
+
+ // Remove tokens
+ if let Some(old_token) = self.userdeviceid_token.remove(&userdeviceid)? {
+ self.token_userdeviceid.remove(&old_token)?;
+ }
+
+ // Remove todevice events
+ let mut prefix = userdeviceid.clone();
+ prefix.push(0xff);
+
+ for result in self.todeviceid_events.scan_prefix(&prefix) {
+ let (key, value) = result?;
+ self.todeviceid_events.remove(key)?;
+ }
+
+ // TODO: Remove onetimekeys
+
+ // Remove the device
+ self.userdeviceids.remove(userdeviceid)?;
+
+ Ok(())
+ }
+
/// Returns an iterator over all device ids of this user.
pub fn all_device_ids(&self, user_id: &UserId) -> impl Iterator- > {
let mut prefix = user_id.to_string().as_bytes().to_vec();
diff --git a/src/main.rs b/src/main.rs
index bf331045..3e34ded3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -29,6 +29,7 @@ fn setup_rocket() -> rocket::Rocket {
client_server::register_route,
client_server::get_login_route,
client_server::login_route,
+ client_server::logout_route,
client_server::get_capabilities_route,
client_server::get_pushrules_all_route,
client_server::set_pushrule_route,