Back to Rocket Chat

Ban User

docs/features/ban-user.md

8.4.06.2 KB
Original Source

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).

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

KeyWhen
user-bannedA user is banned from the room
user-unbannedA user is unbanned (including via re-addition)

REST Endpoints

MethodEndpointDescription
POST/v1/rooms.banUserBan a user (accepts userId or username + roomId)
POST/v1/rooms.unbanUserUnban a user
GET/v1/rooms.bannedUsersList banned users (paginated)

Key Files

LayerFile
API routesapp/api/server/v1/rooms.ts
Validation & permissionsserver/lib/banUserFromRoom.ts
Core ban logicapp/lib/server/functions/banUserFromRoom.ts
Core unban logicapp/lib/server/functions/executeUnbanUserFromRoom.ts
Slash commandsapp/slashcommands-ban/server/ban.ts, unban.ts
Client ban hookclient/views/room/hooks/useBanUser.tsx
Client unban hookclient/views/room/hooks/useUnbanUser.tsx
Ban action (user info)client/views/room/hooks/useUserInfoActions/actions/useBanUserAction.tsx
Banned users UIclient/views/room/contextualBar/BannedUsers/
Subscription typespackages/core-typings/src/ISubscription.ts
REST typingspackages/rest-typings/src/v1/rooms.ts
Model typingspackages/model-typings/src/models/ISubscriptionsModel.ts