From d7f579b308a0b255918ad54033481d60f1f84261 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sun, 11 Oct 2026 12:46:30 +1300 Subject: [PATCH] Add randomized client identifier to reduce chance of grabbing the incorrect subscription ID --- client/homebrew/pages/sharePage/sharePage.jsx | 10 ++++++++-- server/eventStreamSource.js | 5 +++-- server/stream.api.js | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/client/homebrew/pages/sharePage/sharePage.jsx b/client/homebrew/pages/sharePage/sharePage.jsx index 80d544c3a..5a2ff849a 100644 --- a/client/homebrew/pages/sharePage/sharePage.jsx +++ b/client/homebrew/pages/sharePage/sharePage.jsx @@ -16,6 +16,7 @@ import request from '../../utils/request-middleware.js'; import { DEFAULT_BREW_LOAD } from '../../../../server/brewDefaults.js'; import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js'; +import { nanoid } from 'nanoid'; const SharePage = (props)=>{ const { disableMeta = false } = props; @@ -53,14 +54,19 @@ const SharePage = (props)=>{ document.addEventListener('keydown', handleControlKeys); fetchThemeBundle(undefined, setThemeBundle, currentBrew.renderer, currentBrew.theme); + // generate unique fingerprint + const clientFingerprint = nanoid(24); + // listen for changes in the brew version - const eventSource = new EventSource(`/api/stream/${props.brew.shareId}`); + const eventSource = new EventSource(`/api/stream/${props.brew.shareId}?client=${clientFingerprint}`); let subId = ''; eventSource.addEventListener('subscribe', (evt)=>{ const messageData = JSON.parse(evt.data); - subId = messageData.id; + if(messageData.client == clientFingerprint){ + subId = messageData.id; + } }); eventSource.addEventListener('brewUpdated', (evt)=>{ diff --git a/server/eventStreamSource.js b/server/eventStreamSource.js index ac7b1f63c..42539340c 100644 --- a/server/eventStreamSource.js +++ b/server/eventStreamSource.js @@ -20,7 +20,7 @@ const Stream = new EventEmitter; let subscribers = []; // Listener functions -const subscribe = function(shareId, res){ +const subscribe = function(shareId, res, clientFingerprint){ const id = nanoid(24); // NanoID is assumed globally unique; const subscriber = { id, @@ -32,7 +32,7 @@ const subscribe = function(shareId, res){ subscribers.push(subscriber); - Stream.emit('sendUpdate', 'subscribe', { id: subscriber.id, shareId: subscriber.shareId, time: subscriber.time }); + Stream.emit('sendUpdate', 'subscribe', { id: subscriber.id, shareId: subscriber.shareId, client: clientFingerprint, time: subscriber.time }); return subscriber.id; }; @@ -41,6 +41,7 @@ const unsubscribe = function(id){ subscribers .filter((sub)=>{return sub.id == id;}) .forEach((sub)=>{ + clearTimeout(sub.unsubTimer); Stream.emit('sendUpdate', 'unsubscribe', { id: sub.id, shareId: sub.shareId, time: new Date }); }); diff --git a/server/stream.api.js b/server/stream.api.js index 8d162d306..af84b1099 100644 --- a/server/stream.api.js +++ b/server/stream.api.js @@ -13,7 +13,7 @@ app.get('/api/stream/:id', (req, res)=>{ 'Content-Encoding' : 'none' }); ; - Stream.subscribe(req.params.id, res); + Stream.subscribe(req.params.id, res, req.query?.client); }); app.get('/api/stream/unsubscribe/:id', (req, res)=>{