The communications platform that puts data protection first.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Rocket.Chat/docs/features/ban-user.md

116 lines
6.2 KiB

# Ban User
## Overview
Banning prevents a user from participating in a specific room. Unlike kicking (which deletes the subscription), banning **keeps the subscription record** with `status: 'BANNED'`, creating a persistent access barrier.
## Ban Flow
1. A user with `ban-user` permission (roles: `admin`, `owner`, `moderator`) triggers the ban via UI, API (`POST /v1/rooms.banUser`), or slash command (`/ban @username`).
2. **Validations** (`banUserFromRoomMethod` in `server/lib/banUserFromRoom.ts`):
- Checks `ban-user` permission scoped to the room.
- Checks if the room type allows the action (via `roomDirectives.allowMemberAction`).
- Checks if the banning user has access to the room.
- Checks if the target user exists and is in the room.
- Rejects ban if the target is already banned.
- Rejects ban if the target is the last owner.
3. **Execution** (`performUserBan` in `app/lib/server/functions/banUserFromRoom.ts`):
- Updates the subscription to `status: 'BANNED'` (does not delete the record).
- Removes the room from the user's `__rooms` array.
- Decrements the room's `usersCount`.
- Removes room-scoped roles (`moderator`, `owner`, `leader`) in channels and groups.
- If the room is a team's main room, removes the member from the team.
- Saves a `user-banned` system message.
- Notifies the client with a `removed` event on the subscription (so the client drops the stream).
4. **Callback** `afterBanFromRoom` fires (used by Matrix federation to propagate the ban).
## Unban Flow
1. Triggered via UI (contextual bar "Banned Users"), API (`POST /v1/rooms.unbanUser`), or slash command (`/unban @username`).
2. Finds the subscription via `findOneBannedSubscription`.
3. **Removes the subscription entirely** (`Subscriptions.removeById`) — does not restore it to active status.
4. Saves a `user-unbanned` system message.
5. **Callback** `afterUnbanFromRoom` fires (federation).
**Important:** after unban the user **does not become a member** of the room again. The banned subscription is deleted. The user must be invited or join again.
## Join / Invite / Re-entry Behavior
A banned user **cannot** re-enter the room through any path. The ban must be explicitly lifted first. Below is how each entry point enforces this for both normal and federated rooms.
### Invite via API / UI (`groups.invite`, `channels.invite`, "Add Users")
`addUsersToRoom` checks for a `BANNED` subscription before calling `addUserToRoom`:
- Returns `error-user-is-banned` — the invite is rejected.
- The UI shows a warning modal asking the admin to unban first.
- Applies equally to normal and federated rooms (the check is in the method layer, before the room-type branch).
### Invite link (`useInviteToken`)
`useInviteToken` checks for a `BANNED` subscription before saving the invite token or calling `addUserToRoom`:
- Returns `error-user-is-banned` — the token is not consumed.
- Because the check runs before `Users.updateInviteToken`, the secondary path through `setUsername` (for users who register via invite link) is also blocked.
### Direct join (`channels.join`, `joinRoom`)
`Room.join` calls `canAccessRoom` before `addUserToRoom`:
- For **public rooms** and **public rooms inside teams**, the `canAccessRoom` validators explicitly check `findOneBannedSubscription` and deny access.
- For **private rooms**, `countByRoomIdAndUserId` excludes `BANNED` subscriptions (`status: { $exists: false }`), so the "already joined" validator returns false and access is denied.
### Federation invite events
When a Matrix homeserver sends an invite for a user who is banned locally:
- `handleInvite` in `federation-matrix/src/events/member.ts` finds the existing (banned) subscription and returns early without creating a new one.
- The user never receives an `INVITED` subscription, so `handleJoin` is never reached.
### Expected flow
1. **Unban** the user via `POST /v1/rooms.unbanUser`, `/unban @username`, or the "Banned Users" contextual bar. This deletes the banned subscription.
2. **Invite or join** — the user can now be invited (API, UI, invite link) or join (public rooms) normally.
## Access Control
The `canAccessRoom` validators check for bans in two public room scenarios:
- **Public rooms inside teams** — if banned, access is denied.
- **Regular public rooms** — if banned, access is denied.
For private rooms, access is controlled by the subscription: `countByRoomIdAndUserId` excludes `BANNED` subscriptions, so a banned user has no valid subscription and cannot access the room.
## UI
- **Ban action:** appears in the user info panel (inside a room), gated by `ban-user` permission + `roomCanBan` + federation rules.
- **Banned users list:** "Banned Users" tab in the room toolbox (icon: `ban`, order: 13, requires `ban-user`), with virtualized scroll and infinite pagination via `GET /v1/rooms.bannedUsers`.
- **Unban action:** context menu on each item in the banned users list.
- **Confirmation:** both actions show a `GenericModal` with `danger` variant.
## System Messages
| Key | When |
|-----|------|
| `user-banned` | A user is banned from the room |
| `user-unbanned` | A user is unbanned (including via re-addition) |
## REST Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/v1/rooms.banUser` | Ban a user (accepts `userId` or `username` + `roomId`) |
| POST | `/v1/rooms.unbanUser` | Unban a user |
| GET | `/v1/rooms.bannedUsers` | List banned users (paginated) |
## Key Files
| Layer | File |
|-------|------|
| API routes | `app/api/server/v1/rooms.ts` |
| Validation & permissions | `server/lib/banUserFromRoom.ts` |
| Core ban logic | `app/lib/server/functions/banUserFromRoom.ts` |
| Core unban logic | `app/lib/server/functions/executeUnbanUserFromRoom.ts` |
| Slash commands | `app/slashcommands-ban/server/ban.ts`, `unban.ts` |
| Client ban hook | `client/views/room/hooks/useBanUser.tsx` |
| Client unban hook | `client/views/room/hooks/useUnbanUser.tsx` |
| Ban action (user info) | `client/views/room/hooks/useUserInfoActions/actions/useBanUserAction.tsx` |
| Banned users UI | `client/views/room/contextualBar/BannedUsers/` |
| Subscription types | `packages/core-typings/src/ISubscription.ts` |
| REST typings | `packages/rest-typings/src/v1/rooms.ts` |
| Model typings | `packages/model-typings/src/models/ISubscriptionsModel.ts` |