Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
5 changes: 5 additions & 0 deletions .changeset/rich-hounds-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Fixes error messages not showing in the UI when `Preview Public Channel` permission is not in the user role and an app is preventing the same user to join the room.
5 changes: 5 additions & 0 deletions apps/meteor/client/hooks/useJoinRoom.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { sdk } from '../../app/utils/client/lib/SDKClient';
Expand All @@ -11,6 +12,7 @@ type UseJoinRoomMutationFunctionProps = {

export const useJoinRoom = () => {
const queryClient = useQueryClient();
const dispatchToastMessage = useToastMessageDispatch();

return useMutation({
mutationFn: async ({ rid, reference, type }: UseJoinRoomMutationFunctionProps) => {
Expand All @@ -23,5 +25,8 @@ export const useJoinRoom = () => {
queryKey: ['rooms', data],
});
},
onError: (error: unknown) => {
dispatchToastMessage({ message: error, type: 'error' });
},
});
};
1 change: 0 additions & 1 deletion apps/meteor/client/views/room/NotSubscribedRoom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ const NotSubscribedRoom = ({ rid, reference, type }: NotSubscribedRoomProps): Re
const { t } = useTranslation();

const handleJoinClick = useJoinRoom();
// TODO: Handle onJoinClick error

const { isMobile } = useLayout();

Expand Down
5 changes: 3 additions & 2 deletions apps/meteor/client/views/room/composer/ComposerReadOnly.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Button } from '@rocket.chat/fuselage';
import { MessageFooterCallout, MessageFooterCalloutContent } from '@rocket.chat/ui-composer';
import { useEndpoint } from '@rocket.chat/ui-contexts';
import { useEndpoint, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import { useMutation } from '@tanstack/react-query';
import type { ReactElement } from 'react';
import { useTranslation } from 'react-i18next';

import { dispatchToastMessage } from '../../../lib/toast';
import { useRoom, useUserIsSubscribed } from '../contexts/RoomContext';

const ComposerReadOnly = (): ReactElement => {
Expand All @@ -14,6 +13,8 @@ const ComposerReadOnly = (): ReactElement => {
const isSubscribed = useUserIsSubscribed();
const joinChannel = useEndpoint('POST', '/v1/channels.join');

const dispatchToastMessage = useToastMessageDispatch();

const join = useMutation({
mutationFn: () => joinChannel({ roomId: room._id }),

Expand Down
1 change: 1 addition & 0 deletions apps/meteor/tests/e2e/fixtures/inject-initial-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default async function injectInitialData() {
createUserFixture(Users.user2),
createUserFixture(Users.user3),
createUserFixture(Users.userE2EE),
createUserFixture(Users.userNotAllowedByApp),
];

await Promise.all(
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/tests/e2e/fixtures/userStates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export const Users = {
user1: generateContext('user1'),
user2: generateContext('user2'),
user3: generateContext('user3'),
userNotAllowedByApp: generateContext('userNotAllowedByApp'),
userE2EE: generateContext('userE2EE'),
samluser1: generateContext('samluser1'),
samluser2: generateContext('samluser2'),
Expand Down
22 changes: 22 additions & 0 deletions apps/meteor/tests/e2e/page-objects/directory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Page } from '@playwright/test';

export class Directory {
public readonly page: Page;

constructor(page: Page) {
this.page = page;
}

async searchChannel(name: string) {
await this.page.getByRole('textbox', { name: 'Search' }).fill(name);
}

getSearchByChannelName(name: string) {
return this.page.locator(`role=table >> role=link >> text="${name}"`);
}

async openChannel(name: string) {
await this.searchChannel(name);
await this.getSearchByChannelName(name).click();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -459,4 +459,8 @@ export class HomeContent {
get btnClearSelection() {
return this.page.getByRole('button', { name: 'Clear selection' });
}

get btnJoinChannel() {
return this.page.getByRole('button', { name: 'Join channel' });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export class HomeSidenav {
return this.page.locator('#modal-root [data-qa="create-direct-modal"] [data-qa-type="user-auto-complete-input"]');
}

get btnDirectory(): Locator {
return this.page.locator('role=button[name="Directory"]');
}

get btnCreate(): Locator {
return this.page.locator('role=button[name="Create"]');
}
Expand Down Expand Up @@ -140,6 +144,10 @@ export class HomeSidenav {
await this.page.locator(`role=menuitemcheckbox[name="${status}"]`).click();
}

async openDirectory(): Promise<void> {
await this.btnDirectory.click();
}

async openChat(name: string): Promise<void> {
await this.searchRoom(name);
await this.getSearchItemByName(name).click();
Expand Down
86 changes: 86 additions & 0 deletions apps/meteor/tests/e2e/preview-public-channel.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { IS_EE } from './config/constants';
import { Users } from './fixtures/userStates';
import { HomeChannel, Utils } from './page-objects';
import { Directory } from './page-objects/directory';
import { createTargetChannel, sendTargetChannelMessage } from './utils';
import { test, expect } from './utils/test';

test.use({ storageState: Users.admin.state });

test.describe('Preview public channel', () => {
let poHomeChannel: HomeChannel;
let poDirectory: Directory;
let poUtils: Utils;
let targetChannel: string;
let targetChannelMessage: string;

test.beforeEach(async ({ page }) => {
poHomeChannel = new HomeChannel(page);
poDirectory = new Directory(page);
poUtils = new Utils(page);

await page.goto('/home');
});

test.beforeAll(async ({ api }) => {
targetChannel = await createTargetChannel(api);
targetChannelMessage = await sendTargetChannelMessage(api, targetChannel, { msg: 'This message' });

await api.post('/permissions.update', { permissions: [{ _id: 'preview-c-room', roles: ['admin', 'user', 'anonymous'] }] });
});

test.afterAll(async ({ api }) => {
await api.post('/channels.delete', { roomName: targetChannel });
await api.post('/permissions.update', { permissions: [{ _id: 'preview-c-room', roles: ['admin', 'user', 'anonymous'] }] });
});

test.describe('User', () => {
test.use({ storageState: Users.user1.state });

test('should let user preview public rooms messages', async () => {
await poHomeChannel.sidenav.openDirectory();
await poDirectory.openChannel(targetChannel);

await expect(poHomeChannel.content.lastUserMessageBody).toContainText(targetChannelMessage);
});

test('should not let user role preview public rooms', async ({ api }) => {
await api.post('/permissions.update', { permissions: [{ _id: 'preview-c-room', roles: ['admin'] }] });

await poHomeChannel.sidenav.openDirectory();
await poDirectory.openChannel(targetChannel);

await expect(poHomeChannel.content.btnJoinChannel).toBeVisible();
await expect(poHomeChannel.content.lastUserMessageBody).not.toBeVisible();
});
});

test.describe('App', () => {
test.skip(!IS_EE, 'Premium Only');
test.use({ storageState: Users.userNotAllowedByApp.state });

test('should prevent user from join the room', async ({ api }) => {
await api.post('/permissions.update', { permissions: [{ _id: 'preview-c-room', roles: ['admin', 'user', 'anonymous'] }] });
await poHomeChannel.sidenav.openDirectory();
await poDirectory.openChannel(targetChannel);

await expect(poHomeChannel.content.lastUserMessageBody).toContainText(targetChannelMessage);

await poHomeChannel.btnJoinRoom.click();

await expect(poUtils.getAlertByText('TEST OF NOT ALLOWED USER')).toBeVisible();
});

test('should prevent user from join the room without preview permission', async ({ api }) => {
await api.post('/permissions.update', { permissions: [{ _id: 'preview-c-room', roles: ['admin'] }] });

await poHomeChannel.sidenav.openDirectory();
await poDirectory.openChannel(targetChannel);
await expect(poHomeChannel.content.lastUserMessageBody).not.toBeVisible();

await poHomeChannel.content.btnJoinChannel.click();

await expect(poUtils.getAlertByText('TEST OF NOT ALLOWED USER')).toBeVisible();
});
});
});
20 changes: 19 additions & 1 deletion apps/meteor/tests/e2e/utils/create-target-channel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { faker } from '@faker-js/faker';
import type { IRoom } from '@rocket.chat/core-typings';
import type { IRoom, IMessage } from '@rocket.chat/core-typings';
import type { ChannelsCreateProps, GroupsCreateProps } from '@rocket.chat/rest-typings';

import type { BaseTest } from './test';
Expand All @@ -15,6 +15,24 @@ export async function createTargetChannel(api: BaseTest['api'], options?: Omit<C
return name;
}

export async function sendTargetChannelMessage(api: BaseTest['api'], roomName: string, options?: Partial<IMessage>) {
const response = await api.get(`/channels.info?roomName=${roomName}`);

const {
channel: { _id: rid },
}: { channel: IRoom } = await response.json();

await api.post('/chat.sendMessage', {
message: {
rid,
msg: options?.msg || 'simple message',
...options,
},
});

return options?.msg || 'simple message';
}

export async function deleteChannel(api: BaseTest['api'], roomName: string): Promise<void> {
await api.post('/channels.delete', { roomName });
}
Expand Down
Loading