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
5 changes: 5 additions & 0 deletions .changeset/bump-patch-1708114961345.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Bump @rocket.chat/meteor version.
5 changes: 5 additions & 0 deletions .changeset/curly-dodos-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixes an issue not allowing admin users to edit the room name
5 changes: 5 additions & 0 deletions .changeset/large-toys-matter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

fixed an issue with the user presence not updating automatically for other users.
5 changes: 5 additions & 0 deletions .changeset/lucky-ducks-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixed an issue where the login button for Custom OAuth services would not work if any non-custom login service was also available
5 changes: 5 additions & 0 deletions .changeset/serious-cows-compete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Fixed a bug on the rooms page's "Favorite" setting, which previously failed to designate selected rooms as favorites by default.
5 changes: 5 additions & 0 deletions .changeset/silver-chicken-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/livechat": patch
---

fixed livechat UI blinking different colors when the chat is finished
1 change: 1 addition & 0 deletions apps/meteor/app/notifications/client/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './lib/Presence';
4 changes: 3 additions & 1 deletion apps/meteor/app/notifications/client/lib/Presence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { Presence } from '../../../../client/lib/presence';

new Meteor.Streamer('user-presence');

Meteor.StreamerCentral.on('stream-user-presence', (uid: string, username: string, statusChanged?: UserStatus, statusText?: string) => {
type args = [username: string, statusChanged?: UserStatus, statusText?: string];

Meteor.StreamerCentral.on('stream-user-presence', (uid: string, [username, statusChanged, statusText]: args) => {
Presence.notify({ _id: uid, username, status: statusChanged, statusText });
});
1 change: 1 addition & 0 deletions apps/meteor/client/importPackages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import '../app/iframe-login/client';
import '../app/lib/client';
import '../app/message-mark-as-unread/client';
import '../app/nextcloud/client';
import '../app/notifications/client';
import '../app/otr/client';
import '../app/slackbridge/client';
import '../app/slashcommands-archiveroom/client';
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/startup/customOAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Meteor.startup(() => {
loginServices.onLoad((services) => {
for (const service of services) {
if (!('custom' in service && service.custom)) {
return;
continue;
}

new CustomOAuth(service.service, {
Expand Down
12 changes: 6 additions & 6 deletions apps/meteor/client/views/admin/rooms/EditRoom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
TextAreaInput,
FieldError,
} from '@rocket.chat/fuselage';
import { useMutableCallback, useUniqueId } from '@rocket.chat/fuselage-hooks';
import { useEffectEvent, useUniqueId } from '@rocket.chat/fuselage-hooks';
import { useEndpoint, useRouter, useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts';
import React from 'react';
import { useForm, Controller } from 'react-hook-form';
Expand Down Expand Up @@ -96,14 +96,14 @@ const EditRoom = ({ room, onChange, onDelete }: EditRoomProps) => {

const handleArchive = useArchiveRoom(room);

const handleUpdateRoomData = useMutableCallback(async ({ isDefault, roomName, favorite, ...formData }) => {
const handleUpdateRoomData = useEffectEvent(async ({ isDefault, favorite, ...formData }) => {
const data = getDirtyFields(formData, dirtyFields);
delete data.archived;
delete data.favorite;

try {
await saveAction({
rid: room._id,
roomName: roomType === 'd' ? undefined : roomName,
default: isDefault,
favorite: { defaultValue: isDefault, favorite },
...data,
Expand All @@ -117,9 +117,9 @@ const EditRoom = ({ room, onChange, onDelete }: EditRoomProps) => {
}
});

const handleSave = useMutableCallback(async (data) => {
await Promise.all([isDirty && handleUpdateRoomData(data), changeArchiving && handleArchive()].filter(Boolean));
});
const handleSave = useEffectEvent((data) =>
Promise.all([isDirty && handleUpdateRoomData(data), changeArchiving && handleArchive()].filter(Boolean)),
);

const formId = useUniqueId();
const roomNameField = useUniqueId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
Box,
TextAreaInput,
} from '@rocket.chat/fuselage';
import { useMutableCallback, useUniqueId } from '@rocket.chat/fuselage-hooks';
import { useEffectEvent, useUniqueId } from '@rocket.chat/fuselage-hooks';
import type { TranslationKey } from '@rocket.chat/ui-contexts';
import { useSetting, useTranslation, useToastMessageDispatch, useEndpoint } from '@rocket.chat/ui-contexts';
import React, { useMemo } from 'react';
Expand Down Expand Up @@ -98,7 +98,7 @@ const EditRoomInfo = ({ room, onClickClose, onClickBack }: EditRoomInfoProps) =>

const handleArchive = useArchiveRoom(room);

const handleUpdateRoomData = useMutableCallback(async ({ hideSysMes, joinCodeRequired, ...formData }) => {
const handleUpdateRoomData = useEffectEvent(async ({ hideSysMes, joinCodeRequired, ...formData }) => {
const data = getDirtyFields(formData, dirtyFields);
delete data.archived;

Expand All @@ -119,9 +119,9 @@ const EditRoomInfo = ({ room, onClickClose, onClickBack }: EditRoomInfoProps) =>
}
});

const handleSave = useMutableCallback(async (data) => {
await Promise.all([isDirty && handleUpdateRoomData(data), changeArchiving && handleArchive()].filter(Boolean));
});
const handleSave = useEffectEvent((data) =>
Promise.all([isDirty && handleUpdateRoomData(data), changeArchiving && handleArchive()].filter(Boolean)),
);

const formId = useUniqueId();
const roomNameField = useUniqueId();
Expand Down
35 changes: 34 additions & 1 deletion apps/meteor/tests/e2e/administration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,18 @@ test.describe.parallel('administration', () => {
await page.waitForSelector('[qa-room-id="GENERAL"]');
});

test('should edit target channel', async () => {
test('should edit target channel name', async () => {
await poAdmin.inputSearchRooms.fill(targetChannel);
await poAdmin.getRoomRow(targetChannel).click();
await poAdmin.roomNameInput.fill(`${targetChannel}-edited`);
await poAdmin.btnSave.click();

await expect(poAdmin.getRoomRow(targetChannel)).toContainText(`${targetChannel}-edited`);

targetChannel = `${targetChannel}-edited`;
});

test('should edit target channel type', async () => {
await poAdmin.inputSearchRooms.type(targetChannel);
await poAdmin.getRoomRow(targetChannel).click();
await poAdmin.privateLabel.click();
Expand All @@ -87,6 +98,28 @@ test.describe.parallel('administration', () => {
await poAdmin.getRoomRow(targetChannel).click();
await expect(poAdmin.archivedInput).toBeChecked();
});

test.describe.serial('Default rooms', () => {
test('expect target channel to be default', async () => {
await poAdmin.inputSearchRooms.type(targetChannel);
await poAdmin.getRoomRow(targetChannel).click();
await poAdmin.defaultLabel.click();
await poAdmin.btnSave.click();

await poAdmin.getRoomRow(targetChannel).click();
await expect(poAdmin.defaultInput).toBeChecked();
});

test('should mark target default channel as "favorite by default"', async () => {
await poAdmin.inputSearchRooms.type(targetChannel);
await poAdmin.getRoomRow(targetChannel).click();
await poAdmin.favoriteLabel.click();
await poAdmin.btnSave.click();

await poAdmin.getRoomRow(targetChannel).click();
await expect(poAdmin.favoriteInput).toBeChecked();
});
});
});

test.describe('Permissions', () => {
Expand Down
3 changes: 3 additions & 0 deletions apps/meteor/tests/e2e/config/global-setup.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import addCustomOAuth from '../fixtures/addCustomOAuth';
import injectInitialData from '../fixtures/inject-initial-data';
import insertApp from '../fixtures/insert-apps';

export default async function (): Promise<void> {
await injectInitialData();

await insertApp();

await addCustomOAuth();
}
18 changes: 18 additions & 0 deletions apps/meteor/tests/e2e/fixtures/addCustomOAuth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { request } from '@playwright/test';

import { BASE_API_URL } from '../config/constants';
import { Users } from './userStates';

export default async function addCustomOAuth(): Promise<void> {
const api = await request.newContext();

const headers = {
'X-Auth-Token': Users.admin.data.loginToken,
'X-User-Id': Users.admin.data.username,
};

await api.post(`${BASE_API_URL}/settings.addCustomOAuth`, { data: { name: 'Test' }, headers });
await api.post(`${BASE_API_URL}/settings/Accounts_OAuth_Custom-Test`, { data: { value: false }, headers });
await api.post(`${BASE_API_URL}/settings/Accounts_OAuth_Custom-Test-url`, { data: { value: 'https://rocket.chat' }, headers });
await api.post(`${BASE_API_URL}/settings/Accounts_OAuth_Custom-Test-login_style`, { data: { value: 'redirect' }, headers });
}
2 changes: 1 addition & 1 deletion apps/meteor/tests/e2e/fixtures/userStates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type IUserState = {
};

function generateContext(username: string): IUserState {
const date = new Date('2023-02-17T20:38:12.306Z');
const date = new Date();
date.setFullYear(date.getFullYear() + 1);

const token = {
Expand Down
21 changes: 21 additions & 0 deletions apps/meteor/tests/e2e/oauth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,33 @@ test.describe('OAuth', () => {
await expect(poRegistration.btnLoginWithGoogle).toBeVisible();
});

await test.step('expect Custom OAuth button to be visible', async () => {
await expect((await setSettingValueById(api, 'Accounts_OAuth_Custom-Test', true)).status()).toBe(200);
await page.waitForTimeout(5000);
await page.goto('/home');

await expect(poRegistration.btnLoginWithCustomOAuth).toBeVisible();
});

await test.step('expect redirect to the configured URL.', async () => {
await poRegistration.btnLoginWithCustomOAuth.click();
await expect(page).toHaveURL(/https\:\/\/(www)?\.rocket\.chat/);
});

await test.step('expect OAuth button to not be visible', async () => {
await expect((await setSettingValueById(api, 'Accounts_OAuth_Google', false)).status()).toBe(200);
await page.waitForTimeout(5000);

await page.goto('/home');
await expect(poRegistration.btnLoginWithGoogle).not.toBeVisible();
});

await test.step('expect Custom OAuth button to not be visible', async () => {
await expect((await setSettingValueById(api, 'Accounts_OAuth_Custom-Test', false)).status()).toBe(200);
await page.waitForTimeout(5000);

await page.goto('/home');
await expect(poRegistration.btnLoginWithCustomOAuth).not.toBeVisible();
});
});
});
20 changes: 20 additions & 0 deletions apps/meteor/tests/e2e/page-objects/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export class Admin {
return this.page.locator(`label >> text=Private`);
}

get roomNameInput(): Locator {
return this.page.locator('input[name="roomName"]');
}

get archivedLabel(): Locator {
return this.page.locator('label >> text=Archived');
}
Expand All @@ -36,6 +40,22 @@ export class Admin {
return this.page.locator('input[name="archived"]');
}

get favoriteLabel(): Locator {
return this.page.locator('label >> text=Favorite');
}

get favoriteInput(): Locator {
return this.page.locator('input[name="favorite"]');
}

get defaultLabel(): Locator {
return this.page.locator('label >> text=Default');
}

get defaultInput(): Locator {
return this.page.locator('input[name="isDefault"]');
}

get inputSearchUsers(): Locator {
return this.page.locator('input[placeholder="Search Users"]');
}
Expand Down
4 changes: 4 additions & 0 deletions apps/meteor/tests/e2e/page-objects/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export class Registration {
return this.page.locator('role=button[name="Sign in with Google"]');
}

get btnLoginWithCustomOAuth(): Locator {
return this.page.locator('role=button[name="Sign in with Test"]');
}

get goToRegister(): Locator {
return this.page.locator('role=link[name="Create an account"]');
}
Expand Down
4 changes: 3 additions & 1 deletion packages/livechat/src/lib/room.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ export const closeChat = async ({ transcriptRequested } = {}) => {

if (clearLocalStorageWhenChatEnded) {
// exclude UI-affecting flags
const { minimized, visible, undocked, expanded, businessUnit, ...initial } = initialState();
const { iframe: currentIframe } = store.state;
const { minimized, visible, undocked, expanded, businessUnit, config, iframe, ...initial } = initialState();
initial.iframe = { ...currentIframe, guest: {} };
await store.setState(initial);
}

Expand Down
Loading