From 303bca90818bb651ed35e61ef021cd4f08d701de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 13 Jul 2026 12:11:48 +0300 Subject: [PATCH] =?UTF-8?q?fix(bot):=20=D1=81=D0=B2=D0=BE=D0=B9=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=BA=D0=B0=D0=B6=D0=B4=D1=8B=D0=B9=20=D0=B2=D1=85=D0=BE=D0=B4?= =?UTF-8?q?=20=E2=80=94=20=D1=87=D1=83=D0=B6=D0=B8=D0=B5=20=D1=86=D0=B8?= =?UTF-8?q?=D1=84=D1=80=D1=8B=20=D0=BD=D0=B5=20=D0=BE=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=8E=D1=82=D1=81=D1=8F=20=D0=B2=20=D0=B1=D1=80=D0=B0=D1=83?= =?UTF-8?q?=D0=B7=D0=B5=D1=80=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ключ разговора в localStorage теперь привязан к тому, кто вошёл: 'liderra_chat_id_u' в кабинете, 'liderra_chat_id_guest' на лендинге. Смена вошедшего (вход/выход/вход под другим) очищает переписку на экране и заводит новый ключ — иначе следующий человек за тем же компьютером видел бы баланс и проекты прошлого клиента (окошко долбилось бы в чужой разговор и получало 404 от серверной проверки владельца). --- app/public/chat-widget.js | 41 ++++++++++++++++--- .../js/components/support/ChatWidget.vue | 31 ++++++++++++-- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/app/public/chat-widget.js b/app/public/chat-widget.js index 4d13becb..1d453f3c 100644 --- a/app/public/chat-widget.js +++ b/app/public/chat-widget.js @@ -13,7 +13,6 @@ if (window.__liderraChat) return; window.__liderraChat = true; - var KEY = 'liderra_chat_id'; var POLL_MS = 1000; var POLL_LIMIT = 25; // 25 секунд — дальше сдаёмся и говорим честно @@ -26,12 +25,29 @@ ]; var FAILED = 'Что-то пошло не так, ответ не пришёл. Попробуйте ещё раз или напишите на support@liderra.ru.'; - var chatId = localStorage.getItem(KEY); - if (!chatId || !/^[a-f0-9]{32}$/.test(chatId)) { - chatId = (crypto.randomUUID ? crypto.randomUUID() : String(Math.random())).replace(/[^a-f0-9]/g, '').slice(0, 32).padEnd(32, '0'); - localStorage.setItem(KEY, chatId); + // Ключ разговора — СВОЙ на каждый вход: переписка вошедшего содержит его личные цифры + // (баланс, проекты), и следующий человек за тем же компьютером не должен их увидеть. + function keyFor(user) { + return user ? 'liderra_chat_id_u' + user : 'liderra_chat_id_guest'; } + function newChatId() { + return (crypto.randomUUID ? crypto.randomUUID() : String(Math.random())) + .replace(/[^a-f0-9]/g, '').slice(0, 32).padEnd(32, '0'); + } + + function chatIdFor(key) { + var id = localStorage.getItem(key); + if (!id || !/^[a-f0-9]{32}$/.test(id)) { + id = newChatId(); + localStorage.setItem(key, id); + } + return id; + } + + var KEY = keyFor(window.__liderraChatUser || null); + var chatId = chatIdFor(KEY); + var lastId = 0; var busy = false; @@ -225,4 +241,19 @@ input.value = ''; send(text); }; + + // Скрипт грузится один раз за вкладку. Если в этой же вкладке вошли под другим клиентом + // (или вышли), окошко обязано забыть прежний разговор — иначе чужие цифры останутся + // на экране, а сервер будет отвечать 404 на чужой ключ. + window.__liderraChatSetUser = function (user) { + var next = keyFor(user || null); + if (next === KEY) return; + + KEY = next; + chatId = chatIdFor(KEY); + lastId = 0; + busy = false; + while (body.firstChild) body.removeChild(body.firstChild); + if (panel.classList.contains('lch-open')) loadHistory(); + }; })(); diff --git a/app/resources/js/components/support/ChatWidget.vue b/app/resources/js/components/support/ChatWidget.vue index 8dfbe28a..5905fe1c 100644 --- a/app/resources/js/components/support/ChatWidget.vue +++ b/app/resources/js/components/support/ChatWidget.vue @@ -1,15 +1,29 @@