Skip to content

Commit

Permalink
fix(livechat): registering guest multiple times cause message loss (#…
Browse files Browse the repository at this point in the history
…32300)

Co-authored-by: Guilherme Gazzo <5263975+ggazzo@users.noreply.github.com>
  • Loading branch information
dionisio-bot[bot] and ggazzo committed Apr 23, 2024
1 parent 27b5e32 commit dcf4349
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 21 deletions.
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 @@ -460,8 +460,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
75 changes: 56 additions & 19 deletions packages/livechat/src/lib/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,49 @@ import { createToken } from './random';
import { loadMessages } from './room';
import Triggers from './triggers';

const evaluateChangesAndLoadConfigByFields = async (fn) => {
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) => {
const { token } = guest;
token && (await store.setState({ token }));
const { visitor: user } = await Livechat.grantVisitor({ visitor: { ...guest } });
store.setState({ user });
await loadConfig();
};

const updateIframeGuestData = (data) => {
Expand Down Expand Up @@ -76,15 +113,16 @@ const api = {
});
},

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

async _setDepartment(value) {
const {
user,
config: { departments = [] },
defaultAgent,
} = store.state;

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

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

updateIframeGuestData({ department });
Expand All @@ -93,11 +131,6 @@ const api = {
if (defaultAgent && defaultAgent.department !== department) {
store.setState({ defaultAgent: null });
}

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

async setBusinessUnit(newBusinessUnit) {
Expand Down Expand Up @@ -143,7 +176,9 @@ const api = {
if (token === localToken) {
return;
}
await createOrUpdateGuest({ token });
await evaluateChangesAndLoadConfigByFields(async () => {
await createOrUpdateGuest({ token });
});
},

setGuestName(name) {
Expand All @@ -159,17 +194,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);
});
},

async setLanguage(language) {
Expand Down

0 comments on commit dcf4349

Please sign in to comment.