Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/meteor/app/api/server/v1/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ API.v1.addRoute(
async get() {
const findResult = await findChannelByIdOrName({ params: this.queryParams });

const roles = await executeGetRoomRoles(findResult._id, this.userId);
const roles = await executeGetRoomRoles(findResult._id, this.user);

return API.v1.success({
roles,
Expand Down
8 changes: 4 additions & 4 deletions apps/meteor/app/api/server/v1/groups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ async function getRoomFromParams(params: { roomId?: string } | { roomName?: stri
}
})();

if (!room || room.t !== 'p') {
if (room?.t !== 'p') {
throw new Meteor.Error('error-room-not-found', 'The required "roomId" or "roomName" param provided does not match any group');
}

Expand Down Expand Up @@ -273,7 +273,7 @@ API.v1.addRoute(
room = await Rooms.findOneByName(params.roomName || '');
}

if (!room || room.t !== 'p') {
if (room?.t !== 'p') {
throw new Meteor.Error('error-room-not-found', 'The required "roomId" or "roomName" param provided does not match any group');
}

Expand Down Expand Up @@ -791,7 +791,7 @@ API.v1.addRoute(
rid: findResult.rid,
...parseIds(mentionIds, 'mentions._id'),
...parseIds(starredIds, 'starred._id'),
...(pinned && pinned.toLowerCase() === 'true' ? { pinned: true } : {}),
...(pinned?.toLowerCase() === 'true' ? { pinned: true } : {}),
_hidden: { $ne: true },
};

Expand Down Expand Up @@ -1192,7 +1192,7 @@ API.v1.addRoute(
userId: this.userId,
});

const roles = await executeGetRoomRoles(findResult.rid, this.userId);
const roles = await executeGetRoomRoles(findResult.rid, this.user);

return API.v1.success({
roles,
Expand Down
5 changes: 1 addition & 4 deletions apps/meteor/app/api/server/v1/im.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,8 @@ const DmClosePropsSchema = {
roomId: {
type: 'string',
},
userId: {
type: 'string',
},
},
required: ['roomId', 'userId'],
required: ['roomId'],
additionalProperties: false,
};

Expand Down
14 changes: 8 additions & 6 deletions apps/meteor/app/api/server/v1/rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
isRoomsInviteProps,
validateBadRequestErrorResponse,
validateUnauthorizedErrorResponse,
validateForbiddenErrorResponse,
} from '@rocket.chat/rest-typings';
import { isTruthy } from '@rocket.chat/tools';
import { Meteor } from 'meteor/meteor';
Expand Down Expand Up @@ -455,7 +456,6 @@ API.v1.addRoute(
{ authRequired: true /* , validateParams: isRoomsCreateDiscussionProps */ },
{
async post() {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { prid, pmid, reply, t_name, users, encrypted, topic } = this.bodyParams;
if (!prid) {
return API.v1.failure('Body parameter "prid" is required.');
Expand Down Expand Up @@ -550,7 +550,7 @@ API.v1.addRoute(
const [files, total] = await Promise.all([cursor.toArray(), totalCount]);

// If the initial image was not returned in the query, insert it as the first element of the list
if (initialImage && !files.find(({ _id }) => _id === (initialImage as IUpload)._id)) {
if (initialImage && !files.find(({ _id }) => _id === initialImage._id)) {
files.splice(0, 0, initialImage);
}

Expand Down Expand Up @@ -767,7 +767,7 @@ API.v1.addRoute(
void dataExport.sendFile(
{
rid,
format: format as 'html' | 'json',
format,
dateFrom: convertedDateFrom,
dateTo: convertedDateTo,
},
Expand Down Expand Up @@ -815,7 +815,7 @@ API.v1.addRoute(
const [room, user] = await Promise.all([
findRoomByIdOrName({
params: { roomId },
}) as Promise<IRoom>,
}),
Users.findOneByIdOrUsername(userId || username),
]);

Expand Down Expand Up @@ -1070,11 +1070,14 @@ export const roomEndpoints = API.v1
},
required: ['roles'],
}),
400: validateBadRequestErrorResponse,
401: validateUnauthorizedErrorResponse,
403: validateForbiddenErrorResponse,
},
},
async function () {
const { rid } = this.queryParams;
const roles = await executeGetRoomRoles(rid, this.userId);
const roles = await executeGetRoomRoles(rid, this.user);

return API.v1.success({
roles,
Expand Down Expand Up @@ -1246,7 +1249,6 @@ export const roomEndpoints = API.v1
);

type RoomEndpoints = ExtractRoutesFromAPI<typeof roomEndpoints> &
ExtractRoutesFromAPI<typeof roomEndpoints> &
ExtractRoutesFromAPI<typeof roomDeleteEndpoint> &
ExtractRoutesFromAPI<typeof roomsSaveNotificationEndpoint>;

Expand Down
8 changes: 4 additions & 4 deletions apps/meteor/app/lib/server/methods/getRoomRoles.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IRoom } from '@rocket.chat/core-typings';
import type { IRoom, IUser } from '@rocket.chat/core-typings';
import { Rooms } from '@rocket.chat/models';
import { check } from 'meteor/check';
import { Meteor } from 'meteor/meteor';
Expand All @@ -15,10 +15,10 @@ declare module '@rocket.chat/ddp-client' {
}
}

export const executeGetRoomRoles = async (rid: IRoom['_id'], fromUserId?: string | null) => {
export const executeGetRoomRoles = async (rid: IRoom['_id'], fromUser?: IUser | null) => {
check(rid, String);

if (!fromUserId && settings.get('Accounts_AllowAnonymousRead') === false) {
if (!fromUser && settings.get('Accounts_AllowAnonymousRead') === false) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getRoomRoles' });
}

Expand All @@ -27,7 +27,7 @@ export const executeGetRoomRoles = async (rid: IRoom['_id'], fromUserId?: string
throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getRoomRoles' });
}

if (fromUserId && !(await canAccessRoomAsync(room, { _id: fromUserId }))) {
if (fromUser && !(await canAccessRoomAsync(room, fromUser))) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getRoomRoles' });
}

Expand Down
15 changes: 7 additions & 8 deletions apps/meteor/server/methods/loadHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,36 +31,35 @@ declare module '@rocket.chat/ddp-client' {
Meteor.methods<ServerMethods>({
async loadHistory(rid, end, limit = 20, ls, showThreadMessages = true) {
check(rid, String);
const fromUser = await Meteor.userAsync();

if (!Meteor.userId() && settings.get('Accounts_AllowAnonymousRead') === false) {
if (!fromUser && settings.get('Accounts_AllowAnonymousRead') === false) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'loadHistory',
});
}

const fromId = Meteor.userId();

const room = await Rooms.findOneById(rid, { projection: { ...roomAccessAttributes, t: 1 } });
if (!room) {
return false;
}

// this checks the Allow Anonymous Read setting, so no need to check again
if (!(await canAccessRoomAsync(room, fromId ? { _id: fromId } : undefined))) {
if (!(await canAccessRoomAsync(room, fromUser || undefined))) {
return false;
}

// if fromId is undefined and it passed the previous check, the user is reading anonymously
if (!fromId) {
if (!fromUser) {
return loadMessageHistory({ rid, end, limit, ls, showThreadMessages });
}

const canPreview = await hasPermissionAsync(fromId, 'preview-c-room');
const canPreview = await hasPermissionAsync(fromUser._id, 'preview-c-room');

if (room.t === 'c' && !canPreview && !(await Subscriptions.findOneByRoomIdAndUserId(rid, fromId, { projection: { _id: 1 } }))) {
if (room.t === 'c' && !canPreview && !(await Subscriptions.findOneByRoomIdAndUserId(rid, fromUser._id, { projection: { _id: 1 } }))) {
return false;
}

return loadMessageHistory({ userId: fromId, rid, end, limit, ls, showThreadMessages });
return loadMessageHistory({ userId: fromUser._id, rid, end, limit, ls, showThreadMessages });
},
});
18 changes: 7 additions & 11 deletions apps/meteor/server/publications/room/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ Meteor.methods<ServerMethods>({
});
}

const userId = Meteor.userId();
const isAnonymous = !userId;
const user = await Meteor.userAsync();
const isAnonymous = !user?._id;

if (isAnonymous) {
const allowAnon = settings.get('Accounts_AllowAnonymousRead');
Expand All @@ -80,21 +80,17 @@ Meteor.methods<ServerMethods>({
}

if (
userId &&
!(await canAccessRoomAsync(
room,
{ _id: userId },
{
includeInvitations: true,
},
))
user &&
!(await canAccessRoomAsync(room, user, {
includeInvitations: true,
}))
) {
throw new Meteor.Error('error-no-permission', 'No permission', {
method: 'getRoomByTypeAndName',
});
}

if (settings.get('Store_Last_Message') && userId && !(await hasPermissionAsync(userId, 'preview-c-room'))) {
if (settings.get('Store_Last_Message') && user && !(await hasPermissionAsync(user._id, 'preview-c-room'))) {
delete room.lastMessage;
}

Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/server/services/authorization/canAccessRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const roomAccessValidators: RoomAccessValidatorConverted[] = [
canAccessRoomLivechat,
];

const isPartialUser = (user: IUser | Pick<IUser, '_id'> | undefined): user is Pick<IUser, '_id'> => {
export const isPartialUser = (user: IUser | Pick<IUser, '_id'> | undefined): user is Pick<IUser, '_id'> => {
return Boolean(user && Object.keys(user).length === 1 && '_id' in user);
};

Expand Down
15 changes: 8 additions & 7 deletions apps/meteor/server/services/authorization/canReadRoom.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import type { RoomAccessValidator } from '@rocket.chat/core-services';
import { Authorization } from '@rocket.chat/core-services';
import { Subscriptions } from '@rocket.chat/models';
import { Subscriptions, Users } from '@rocket.chat/models';

import { canAccessRoom } from './canAccessRoom';
import { canAccessRoom, isPartialUser } from './canAccessRoom';

export const canReadRoom: RoomAccessValidator = async (...args) => {
const [room, user] = args;
const userArgument = isPartialUser(user) ? await Users.findOneById(user._id) : user;

if (!(await canAccessRoom(...args))) {
return false;
}

const [room, user] = args;

if (
user?._id &&
userArgument &&
room?.t === 'c' &&
!(await Authorization.hasPermission(user._id, 'preview-c-room')) &&
!(await Subscriptions.findOneByRoomIdAndUserId(room?._id, user._id, { projection: { _id: 1 } }))
!(await Authorization.hasPermission(userArgument, 'preview-c-room')) &&
!(await Subscriptions.findOneByRoomIdAndUserId(room?._id, userArgument._id, { projection: { _id: 1 } }))
) {
return false;
}
Expand Down
1 change: 0 additions & 1 deletion apps/meteor/tests/end-to-end/api/direct-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,6 @@ describe('[Direct Messages]', () => {
.set(credentials)
.send({
roomId: directMessage._id,
userId: user._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
Expand Down
Loading