From 2efcefc5f08d73fcb519b38ec4c12f81cc6b8bc2 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Tue, 2 Apr 2024 20:01:13 -0300 Subject: [PATCH] apps/meteor/app/authentication/server/startup/index.js --- .changeset/nine-houses-reply.md | 6 ++ .../omnichannel-livechat-api.spec.ts | 2 - packages/livechat/src/lib/hooks.js | 75 ++++++++++++++----- 3 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 .changeset/nine-houses-reply.md diff --git a/.changeset/nine-houses-reply.md b/.changeset/nine-houses-reply.md new file mode 100644 index 0000000000000..29bbe0882a76c --- /dev/null +++ b/.changeset/nine-houses-reply.md @@ -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. diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts index 5d1d05c7c69fe..772789e109192 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts @@ -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(); diff --git a/packages/livechat/src/lib/hooks.js b/packages/livechat/src/lib/hooks.js index 67e3313719485..c29a595f65aa3 100644 --- a/packages/livechat/src/lib/hooks.js +++ b/packages/livechat/src/lib/hooks.js @@ -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) => { @@ -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 }); @@ -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) { @@ -143,7 +176,9 @@ const api = { if (token === localToken) { return; } - await createOrUpdateGuest({ token }); + await evaluateChangesAndLoadConfigByFields(async () => { + await createOrUpdateGuest({ token }); + }); }, setGuestName(name) { @@ -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) {