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
6 changes: 6 additions & 0 deletions .changeset/nine-houses-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@rocket.chat/meteor": patch
"@rocket.chat/livechat": patch
---

Livechat: A registered user loses their messages if 'registerGuest' is called using the same token.
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,6 @@ test.describe('OC - Livechat API', () => {
await poLiveChat.btnSendMessageToOnlineAgent.click();

await expect(poLiveChat.txtChatMessage('this_a_test_message_from_visitor_1')).toBeVisible();

});

await test.step('Expect registerGuest to create guest 2', async () => {
Expand All @@ -448,7 +447,6 @@ test.describe('OC - Livechat API', () => {

await poLiveChat.txtChatMessage('this_a_test_message_from_visitor_2').waitFor({ state: 'visible' });
await expect(poLiveChat.txtChatMessage('this_a_test_message_from_visitor_2')).toBeVisible();

});
});

Expand All @@ -460,8 +458,6 @@ test.describe('OC - Livechat API', () => {
};

await test.step('Expect registerGuest work with the same token, multiple times', async () => {
test.fail();

await poLiveChat.page.evaluate(() => window.RocketChat.livechat.maximizeWidget());
await expect(page.frameLocator('#rocketchat-iframe').getByText('Start Chat')).toBeVisible();

Expand Down
74 changes: 57 additions & 17 deletions packages/livechat/src/lib/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,49 @@ import { createToken } from './random';
import { loadMessages } from './room';
import Triggers from './triggers';

const evaluateChangesAndLoadConfigByFields = async (fn: () => Promise<void>) => {
const oldStore = JSON.parse(
JSON.stringify({
user: store.state.user || {},
department: store.state.department,
token: store.state.token,
}),
);
await fn();

/**
* it solves the issues where the registerGuest is called every time the widget is opened
* and the guest is already registered. If there is nothing different in the data,
* it will not call the loadConfig again.
*
* if user changes, it will call loadConfig
* if department changes, it will call loadConfig
* if token changes, it will call loadConfig
*/

if (oldStore.user._id !== store.state.user?._id) {
await loadConfig();
await loadMessages();
return;
}

if (oldStore.department !== store.state.department) {
await loadConfig();
await loadMessages();
return;
}

if (oldStore.token !== store.state.token) {
await loadConfig();
await loadMessages();
}
};

const createOrUpdateGuest = async (guest: StoreState['guest']) => {
if (!guest) {
return;
}

const { token } = guest;
token && (await store.setState({ token }));
const { visitor: user } = await Livechat.grantVisitor({ visitor: { ...guest } });
Expand All @@ -23,7 +62,6 @@ const createOrUpdateGuest = async (guest: StoreState['guest']) => {
return;
}
store.setState({ user } as Omit<StoreState['user'], 'ts'>);
await loadConfig();
Triggers.callbacks?.emit('chat-visitor-registered');
};

Expand Down Expand Up @@ -97,6 +135,10 @@ const api = {
},

setDepartment: async (value: string) => {
await evaluateChangesAndLoadConfigByFields(async () => api._setDepartment(value));
},

_setDepartment: async (value: string) => {
const {
user,
config: { departments = [] },
Expand All @@ -108,8 +150,6 @@ const api = {
return;
}

const { department: existingDepartment } = user || {};

const department = departments.find((dep) => dep._id === value || dep.name === value)?._id || '';

if (!department) {
Expand All @@ -124,11 +164,6 @@ const api = {
if (defaultAgent && defaultAgent.department !== department) {
store.setState({ defaultAgent: undefined });
}

if (department !== existingDepartment) {
await loadConfig();
await loadMessages();
}
},

setBusinessUnit: async (newBusinessUnit: string) => {
Expand Down Expand Up @@ -185,7 +220,10 @@ const api = {
if (token === localToken) {
return;
}
await createOrUpdateGuest({ token });

await evaluateChangesAndLoadConfigByFields(async () => {
await createOrUpdateGuest({ token });
});
},

setGuestName: (name: string) => {
Expand All @@ -201,17 +239,19 @@ const api = {
return;
}

if (!data.token) {
data.token = createToken();
}
await evaluateChangesAndLoadConfigByFields(async () => {
if (!data.token) {
data.token = createToken();
}

if (data.department) {
api.setDepartment(data.department);
}
if (data.department) {
await api._setDepartment(data.department);
}

Livechat.unsubscribeAll();
Livechat.unsubscribeAll();

await createOrUpdateGuest(data);
await createOrUpdateGuest(data);
});
},

setLanguage: async (language: StoreState['iframe']['language']) => {
Expand Down