Skip to content

Commit 8e99a2e

Browse files
authored
fix: Users without preview permission possibility of subscribe to public channel stream (#35194)
1 parent 43cc75b commit 8e99a2e

File tree

6 files changed

+39
-22
lines changed

6 files changed

+39
-22
lines changed

.changeset/lemon-lions-learn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@rocket.chat/meteor": patch
3+
---
4+
5+
fixes the possibility of see new messages without being subscribed to a public channel.

apps/meteor/app/lib/server/methods/getChannelHistory.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1+
import { Authorization } from '@rocket.chat/core-services';
12
import type { IMessage, MessageTypesValues } from '@rocket.chat/core-typings';
23
import type { ServerMethods } from '@rocket.chat/ddp-client';
3-
import { Messages, Subscriptions, Rooms } from '@rocket.chat/models';
4+
import { Messages, Rooms } from '@rocket.chat/models';
45
import { check } from 'meteor/check';
56
import { Meteor } from 'meteor/meteor';
67

7-
import { canAccessRoomAsync } from '../../../authorization/server';
8-
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
98
import { settings } from '../../../settings/server/cached';
109
import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser';
1110
import { getHiddenSystemMessages } from '../lib/getHiddenSystemMessages';
@@ -62,16 +61,8 @@ export const getChannelHistory = async ({
6261
return false;
6362
}
6463

65-
if (!(await canAccessRoomAsync(room, { _id: fromUserId }))) {
66-
return false;
67-
}
68-
6964
// Make sure they can access the room
70-
if (
71-
room.t === 'c' &&
72-
!(await hasPermissionAsync(fromUserId, 'preview-c-room')) &&
73-
!(await Subscriptions.findOneByRoomIdAndUserId(rid, fromUserId, { projection: { _id: 1 } }))
74-
) {
65+
if (!(await Authorization.canReadRoom(room, { _id: fromUserId }))) {
7566
return false;
7667
}
7768

apps/meteor/server/modules/notifications/notifications.module.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,16 +101,7 @@ export class NotificationsModule {
101101
return false;
102102
}
103103

104-
const canAccess = await Authorization.canAccessRoom(room, { _id: this.userId || '' }, extraData);
105-
if (!canAccess) {
106-
// verify if can preview messages from public channels
107-
if (room.t === 'c' && this.userId) {
108-
return Authorization.hasPermission(this.userId, 'preview-c-room');
109-
}
110-
return false;
111-
}
112-
113-
return true;
104+
return Authorization.canReadRoom(room, { _id: this.userId || '' }, extraData);
114105
});
115106

116107
this.streamRoomMessage.allowRead('__my_messages__', 'all');
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import type { RoomAccessValidator } from '@rocket.chat/core-services';
2+
import { Authorization } from '@rocket.chat/core-services';
3+
import { Subscriptions } from '@rocket.chat/models';
4+
5+
import { canAccessRoom } from './canAccessRoom';
6+
7+
export const canReadRoom: RoomAccessValidator = async (...args) => {
8+
if (!(await canAccessRoom(...args))) {
9+
return false;
10+
}
11+
12+
const [room, user] = args;
13+
14+
if (
15+
user?._id &&
16+
room?.t === 'c' &&
17+
!(await Authorization.hasPermission(user._id, 'preview-c-room')) &&
18+
!(await Subscriptions.findOneByRoomIdAndUserId(room?._id, user._id, { projection: { _id: 1 } }))
19+
) {
20+
return false;
21+
}
22+
23+
return true;
24+
};

apps/meteor/server/services/authorization/service.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Subscriptions, Rooms, Users, Roles, Permissions } from '@rocket.chat/mo
55
import mem from 'mem';
66

77
import { canAccessRoom } from './canAccessRoom';
8+
import { canReadRoom } from './canReadRoom';
89
import { AuthorizationUtils } from '../../../app/authorization/lib/AuthorizationUtils';
910

1011
import './canAccessRoomLivechat';
@@ -80,6 +81,10 @@ export class Authorization extends ServiceClass implements IAuthorization {
8081
return canAccessRoom(...args);
8182
}
8283

84+
async canReadRoom(...args: Parameters<RoomAccessValidator>): Promise<boolean> {
85+
return canReadRoom(...args);
86+
}
87+
8388
async canAccessRoomId(rid: IRoom['_id'], uid: IUser['_id']): Promise<boolean> {
8489
const room = await Rooms.findOneById<Pick<IRoom, '_id' | 't' | 'teamId' | 'prid'>>(rid, {
8590
projection: {

packages/core-services/src/types/IAuthorization.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export interface IAuthorization {
1111
hasPermission(userId: string, permissionId: string, scope?: string): Promise<boolean>;
1212
hasAtLeastOnePermission(userId: string, permissions: string[], scope?: string): Promise<boolean>;
1313
canAccessRoom: RoomAccessValidator;
14+
canReadRoom: RoomAccessValidator;
1415
canAccessRoomId(rid: IRoom['_id'], uid?: IUser['_id']): Promise<boolean>;
1516
getUsersFromPublicRoles(): Promise<(IRocketChatRecord & Pick<IUser, '_id' | 'username' | 'roles'>)[]>;
1617
}

0 commit comments

Comments
 (0)