diff --git a/packages/rocketchat-api/server/v1/channels.js b/packages/rocketchat-api/server/v1/channels.js index 73e38b2cda85..55a870b526b6 100644 --- a/packages/rocketchat-api/server/v1/channels.js +++ b/packages/rocketchat-api/server/v1/channels.js @@ -557,6 +557,10 @@ RocketChat.API.v1.addRoute('channels.members', { authRequired: true }, { returnUsernames: true }); + if (findResult.broadcast && !RocketChat.authz.hasPermission(this.userId, 'view-broadcast-member-list')) { + return RocketChat.API.v1.unauthorized(); + } + const { offset, count } = this.getPaginationItems(); const { sort } = this.parseJsonQuery(); diff --git a/packages/rocketchat-api/server/v1/groups.js b/packages/rocketchat-api/server/v1/groups.js index 03829f9b73a5..73fa7d3cc113 100644 --- a/packages/rocketchat-api/server/v1/groups.js +++ b/packages/rocketchat-api/server/v1/groups.js @@ -449,6 +449,11 @@ RocketChat.API.v1.addRoute('groups.listAll', { authRequired: true }, { RocketChat.API.v1.addRoute('groups.members', { authRequired: true }, { get() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); + + if (findResult._room.broadcast && !RocketChat.authz.hasPermission(this.userId, 'view-broadcast-member-list')) { + return RocketChat.API.v1.unauthorized(); + } + const { offset, count } = this.getPaginationItems(); const { sort } = this.parseJsonQuery(); diff --git a/packages/rocketchat-authorization/server/startup.js b/packages/rocketchat-authorization/server/startup.js index 142de2284a1c..85c2d02a3745 100644 --- a/packages/rocketchat-authorization/server/startup.js +++ b/packages/rocketchat-authorization/server/startup.js @@ -67,7 +67,8 @@ Meteor.startup(function() { { _id: 'view-statistics', roles : ['admin'] }, { _id: 'view-user-administration', roles : ['admin'] }, { _id: 'preview-c-room', roles : ['admin', 'user', 'anonymous'] }, - { _id: 'view-outside-room', roles : ['admin', 'owner', 'moderator', 'user'] } + { _id: 'view-outside-room', roles : ['admin', 'owner', 'moderator', 'user'] }, + { _id: 'view-broadcast-member-list', roles : ['admin', 'owner', 'moderator'] } ]; for (const permission of permissions) { diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index df63828c68bd..b66c632cbadd 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -2322,6 +2322,7 @@ "Video_message": "Video message", "Videocall_declined": "Video Call Declined.", "Videocall_enabled": "Video Call Enabled", + "view-broadcast-member-list": "View Members List in Broadcast Room", "view-c-room": "View Public Channel", "view-c-room_description": "Permission to view public channels", "view-d-room": "View Direct Messages", diff --git a/packages/rocketchat-lib/client/defaultTabBars.js b/packages/rocketchat-lib/client/defaultTabBars.js index 34daa2afee46..1655ad72ea2d 100644 --- a/packages/rocketchat-lib/client/defaultTabBars.js +++ b/packages/rocketchat-lib/client/defaultTabBars.js @@ -33,7 +33,7 @@ RocketChat.TabBar.addButton({ return true; } - return RocketChat.authz.hasRole(Meteor.userId(), ['admin', 'moderator', 'owner'], rid); + return RocketChat.authz.hasAllPermission('view-broadcast-member-list', rid); } }); diff --git a/server/methods/getUsersOfRoom.js b/server/methods/getUsersOfRoom.js index 2ba96ed29f81..3a6bc5c2e66a 100644 --- a/server/methods/getUsersOfRoom.js +++ b/server/methods/getUsersOfRoom.js @@ -9,6 +9,10 @@ Meteor.methods({ throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getUsersOfRoom' }); } + if (room.broadcast && !RocketChat.authz.hasPermission(Meteor.userId(), 'view-broadcast-member-list', roomId)) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getUsersOfRoom' }); + } + const filter = (record) => { if (!record._user) { console.log('Subscription without user', record._id);