Skip to content
6 changes: 2 additions & 4 deletions apps/meteor/client/views/room/RoomOpenerEmbedded.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,11 @@ const RoomOpenerEmbedded = ({ type, reference }: RoomOpenerProps): ReactElement
return;
}
return subscribeToNotifyUser(`${uid}/subscriptions-changed`, (event, sub) => {
if (event !== 'inserted') {
if (sub.rid !== rid || event === 'removed') {
return;
}

if (sub.rid === rid) {
refetch();
}
refetch();
});
}, [refetch, rid, subscribeToNotifyUser, uid]);

Expand Down
14 changes: 5 additions & 9 deletions apps/meteor/client/views/room/hooks/useOpenRoom.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isPublicRoom, isInviteSubscription, type IRoom, type RoomType } from '@rocket.chat/core-typings';
import { isPublicRoom, type IRoom, type RoomType } from '@rocket.chat/core-typings';
import { getObjectKeys } from '@rocket.chat/tools';
import { useMethod, usePermission, useRoute, useSetting, useUser } from '@rocket.chat/ui-contexts';
import { useQuery, useQueryClient } from '@tanstack/react-query';
Expand Down Expand Up @@ -35,14 +35,6 @@ export function useOpenRoom({ type, reference }: { type: RoomType; reference: st
throw new RoomNotFoundError(undefined, { type, reference });
}

const { Rooms, Subscriptions } = await import('../../../stores');

const sub = Subscriptions.state.find((record) => record.rid === reference || record.name === reference);

if (sub && isInviteSubscription(sub)) {
return { rid: sub.rid };
}

let roomData: IRoom;
try {
roomData = await getRoomByTypeAndName(type, reference);
Expand All @@ -66,6 +58,8 @@ export function useOpenRoom({ type, reference }: { type: RoomType; reference: st
throw new RoomNotFoundError(undefined, { type, reference });
}

const { Rooms, Subscriptions } = await import('../../../stores');

const unsetKeys = getObjectKeys(roomData).filter((key) => !(key in roomFields));
unsetKeys.forEach((key) => {
delete roomData[key];
Expand All @@ -80,6 +74,8 @@ export function useOpenRoom({ type, reference }: { type: RoomType; reference: st

const { LegacyRoomManager } = await import('../../../../app/ui-utils/client');

const sub = Subscriptions.state.find((record) => record.rid === reference || record.name === reference);

if (reference !== undefined && room._id !== reference && type === 'd') {
// Redirect old url using username to rid
LegacyRoomManager.close(type + reference);
Expand Down
3 changes: 2 additions & 1 deletion apps/meteor/client/views/room/hooks/useRoomInvitation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useQueryClient } from '@tanstack/react-query';

import { useRoomRejectInvitationModal } from './useRoomRejectInvitationModal';
import { useEndpointMutation } from '../../../hooks/useEndpointMutation';
import { roomsQueryKeys } from '../../../lib/queryKeys';
import { roomsQueryKeys, subscriptionsQueryKeys } from '../../../lib/queryKeys';
import type { IRoomWithFederationOriginalName } from '../contexts/RoomContext';

export const useRoomInvitation = (room: IRoomWithFederationOriginalName) => {
Expand All @@ -24,6 +24,7 @@ export const useRoomInvitation = (room: IRoomWithFederationOriginalName) => {
}

await queryClient.invalidateQueries({ queryKey: roomsQueryKeys.room(room._id) });
await queryClient.invalidateQueries({ queryKey: subscriptionsQueryKeys.subscription(room._id) });

if (action === 'reject') {
router.navigate('/home');
Expand Down
11 changes: 10 additions & 1 deletion apps/meteor/server/publications/room/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,16 @@ Meteor.methods<ServerMethods>({
});
}

if (userId && !(await canAccessRoomAsync(room, { _id: userId }))) {
if (
userId &&
!(await canAccessRoomAsync(
room,
{ _id: userId },
{
includeInvitations: true,
},
))
) {
throw new Meteor.Error('error-no-permission', 'No permission', {
method: 'getRoomByTypeAndName',
});
Expand Down
5 changes: 3 additions & 2 deletions apps/meteor/server/services/authorization/canAccessRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const roomAccessValidators: RoomAccessValidator[] = [
return canAccessPublicRoom(user);
},

async function _validateIfAlreadyJoined(room, user): Promise<boolean> {
async function _validateIfAlreadyJoined(room, user, extraData): Promise<boolean> {
if (!room?._id || !user?._id) {
return false;
}
Expand All @@ -67,7 +67,8 @@ const roomAccessValidators: RoomAccessValidator[] = [
!(await License.hasModule('abac')) ||
(!(await Settings.getValueById('ABAC_Enabled')) as boolean)
) {
if (!(await Subscriptions.countByRoomIdAndUserId(room._id, user._id))) {
const includeInvitations = extraData?.includeInvitations ?? false;
if (!(await Subscriptions.countByRoomIdAndUserId(room._id, user._id, includeInvitations))) {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/model-typings/src/models/ISubscriptionsModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export interface ISubscriptionsModel extends IBaseModel<ISubscription> {

findByLivechatRoomIdAndNotUserId(roomId: string, userId: string, options?: FindOptions<ISubscription>): FindCursor<ISubscription>;

countByRoomIdAndUserId(rid: string, uid: string | undefined): Promise<number>;
countByRoomIdAndUserId(rid: string, uid: string | undefined, includeInvitations?: boolean): Promise<number>;

countUnarchivedByRoomId(rid: string): Promise<number>;

Expand Down
4 changes: 2 additions & 2 deletions packages/models/src/models/Subscriptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,11 @@ export class SubscriptionsRaw extends BaseRaw<ISubscription> implements ISubscri
return this.find(query, options);
}

countByRoomIdAndUserId(rid: string, uid: string | undefined): Promise<number> {
countByRoomIdAndUserId(rid: string, uid: string | undefined, includeInvitations = false): Promise<number> {
const query = {
rid,
'u._id': uid,
'status': { $exists: false },
...(includeInvitations ? { $or: [{ status: { $exists: false } }, { status: 'INVITED' as const }] } : { status: { $exists: false } }),
};

return this.countDocuments(query);
Expand Down
Loading