mirror of
https://forgejo.ellis.link/continuwuation/continuwuity/
synced 2026-04-02 09:15:39 +00:00
Compare commits
5 Commits
tom/max-pe
...
nex/feat/a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c716befdc | ||
|
|
a8209d1dd9 | ||
|
|
9552dd7485 | ||
|
|
88c84f221f | ||
|
|
a10bd71945 |
1
changelog.d/1271.feature
Normal file
1
changelog.d/1271.feature
Normal file
@@ -0,0 +1 @@
|
||||
Added admin command to forcefully log out all of a user's existing sessions. Contributed by @nex.
|
||||
@@ -1017,3 +1017,29 @@ pub(super) async fn unlock(&self, user_id: String) -> Result {
|
||||
self.write_str(&format!("User {user_id} has been unlocked."))
|
||||
.await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn logout(&self, user_id: String) -> Result {
|
||||
self.bail_restricted()?;
|
||||
let user_id = parse_local_user_id(self.services, &user_id)?;
|
||||
assert!(
|
||||
self.services.globals.user_is_local(&user_id),
|
||||
"Parsed user_id must be a local user"
|
||||
);
|
||||
if user_id == self.services.globals.server_user {
|
||||
return Err!("Not allowed to log out the server service account.",);
|
||||
}
|
||||
|
||||
if !self.services.users.exists(&user_id).await {
|
||||
return Err!("User {user_id} does not exist.");
|
||||
}
|
||||
if self.services.users.is_admin(&user_id).await {
|
||||
return Err!("You cannot forcefully log out admin users.");
|
||||
}
|
||||
self.services
|
||||
.users
|
||||
.all_device_ids(&user_id)
|
||||
.for_each(|device_id| self.services.users.remove_device(&user_id, device_id))
|
||||
.await;
|
||||
self.write_str(&format!("User {user_id} has been logged out from all devices."))
|
||||
}
|
||||
|
||||
@@ -59,6 +59,18 @@ pub enum UserCommand {
|
||||
force: bool,
|
||||
},
|
||||
|
||||
/// - Forcefully log a user out of all of their devices.
|
||||
///
|
||||
/// This will invalidate all access tokens for the specified user,
|
||||
/// effectively logging them out from all sessions.
|
||||
/// Note that this is destructive and may result in data loss for the user,
|
||||
/// such as encryption keys. Use with caution. Can only be used in the admin
|
||||
/// room.
|
||||
Logout {
|
||||
/// Username of the user to log out
|
||||
user_id: String,
|
||||
},
|
||||
|
||||
/// - Suspend a user
|
||||
///
|
||||
/// Suspended users are able to log in, sync, and read messages, but are not
|
||||
|
||||
@@ -178,7 +178,20 @@ pub async fn leave_room(
|
||||
.rooms
|
||||
.state_cache
|
||||
.left_state(user_id, room_id)
|
||||
.await?
|
||||
.await
|
||||
.inspect_err(|err| {
|
||||
// `left_state` may return an Err if the user _is_ in the room they're
|
||||
// trying to leave, but the membership cache is incorrect and
|
||||
// they're cached as being joined. In this situation
|
||||
// we save a `None` to the `roomuserid_leftcount` table, which generates
|
||||
// and sends a dummy leave to the client.
|
||||
warn!(
|
||||
?err,
|
||||
"Trying to leave room not cached as leave, sending dummy leave \
|
||||
event to client"
|
||||
);
|
||||
})
|
||||
.unwrap_or_default()
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user