From ccbd63ba798c9d06db0da784195a233ee5e8c840 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Jul 2026 22:41:06 -0500 Subject: [PATCH] Stamp the authenticated device on relayed playback progress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit device:playback-state was the only relay that forwarded the client's payload verbatim. The workspace lookup correctly used currentDeviceId — the socket's authenticated device — but the object passed on to the dashboard was whatever the player sent, including any device_id it chose to put there. So one device could report playback progress attributed to a different screen in the same workspace, and the dashboard had no reason to doubt it. Every other relay in this file stamps the authenticated id. This one now matches. 882 server tests green. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL --- server/ws/deviceSocket.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/server/ws/deviceSocket.js b/server/ws/deviceSocket.js index 16776d5..16006cd 100644 --- a/server/ws/deviceSocket.js +++ b/server/ws/deviceSocket.js @@ -1108,9 +1108,14 @@ module.exports = function setupDeviceSocket(io) { // Playback state update socket.on('device:playback-state', (data) => { if (!requireDeviceAuth()) return; - // currentDeviceId is the authenticated device for this socket; use it - // for the workspace lookup since data may not carry device_id consistently. - emitToDeviceWorkspace(dashboardNs, currentDeviceId, 'dashboard:playback-state', data); + // currentDeviceId is the authenticated device for this socket; use it for the workspace + // lookup since data may not carry device_id consistently — and STAMP it over whatever the + // payload claims before relaying. This was the only relay forwarding the client's object + // verbatim, so a device could report progress attributed to a different screen in the same + // workspace and the dashboard would believe it. Every other relay here stamps the + // authenticated id; this one now matches. + emitToDeviceWorkspace(dashboardNs, currentDeviceId, 'dashboard:playback-state', + { ...(data || {}), device_id: currentDeviceId }); }); // Live debug log line from the player (only sent when debug logging is toggled