diff --git a/src/controllers/user_ws_controller.rs b/src/controllers/user_ws_controller.rs index 7503973..36c5508 100644 --- a/src/controllers/user_ws_controller.rs +++ b/src/controllers/user_ws_controller.rs @@ -16,13 +16,14 @@ use crate::constants::WS_ACCESS_TOKEN_LENGTH; use crate::controllers::user_ws_controller::ws_connections_list::{add_connection, find_connection, get_ws_connections_list, remove_connection}; pub use crate::controllers::user_ws_controller::ws_connections_list::WsConnection; use crate::controllers::user_ws_routes::find_user_ws_route; +use crate::data::api_client::APIClient; use crate::data::base_request_handler::BaseRequestHandler; use crate::data::config::conf; use crate::data::error::{ExecError, Res, ResultBoxError}; use crate::data::http_request_handler::HttpRequestHandler; use crate::data::user::UserID; -use crate::data::user_ws_request_handler::{WsRequestHandler, WsResponseType}; use crate::data::user_ws_message::UserWsMessage; +use crate::data::user_ws_request_handler::{WsRequestHandler, WsResponseType}; use crate::utils::crypt_utils::rand_str; use crate::utils::date_utils::time; @@ -108,6 +109,7 @@ mod ws_connections_list { #[derive(Clone, Debug)] pub struct WsConnection { pub user_id: UserID, + pub client_id: u32, pub remote_ip: String, pub session: actix::Addr, } @@ -276,6 +278,7 @@ impl Actor for WsSession { add_connection(WsConnection { user_id: self.user_id.clone(), + client_id: self.client_id, remote_ip: self.remote_ip.clone(), session: ctx.address(), }) @@ -434,7 +437,24 @@ pub fn is_user_connected(user_id: &UserID) -> bool { get_ws_connections_list().lock().unwrap().iter().any(|c| &c.user_id == user_id) } -/// Disconnect a user from WebSocket +/// Disconnect a user from all the WebSockets of a given client +pub fn disconnect_user_from_client(user_id: &UserID, client: &APIClient) -> Res { + let connections = get_ws_connections_list() + .lock() + .unwrap() + .iter() + .filter(|f| &f.user_id == user_id && f.client_id == client.id) + .map(|f| f.session.clone()) + .collect::>>(); + + for c in connections { + c.do_send(WsCloseConnection {}); + } + + Ok(()) +} + +/// Disconnect a user from all its WebSocket pub fn disconnect_user_from_all_sockets(user_id: &UserID) -> Res { let connections = get_ws_connections_list() .lock() diff --git a/src/helpers/account_helper.rs b/src/helpers/account_helper.rs index 3f1bb18..289d354 100644 --- a/src/helpers/account_helper.rs +++ b/src/helpers/account_helper.rs @@ -107,6 +107,8 @@ pub fn exists_mail(mail: &str) -> ResultBoxError { /// Destroy a given user login tokens pub fn destroy_login_tokens(id: &UserID, client: &APIClient) -> ResultBoxError<()> { + user_ws_controller::disconnect_user_from_client(id, client)?; + database::delete(DeleteQuery::new(USER_ACCESS_TOKENS_TABLE) .cond_u32("service_id", client.id) .cond_user_id("user_id", id)