Stamp the authenticated device on relayed playback progress

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) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
This commit is contained in:
Claude 2026-07-30 22:41:06 -05:00
parent a310d7d5b6
commit ccbd63ba79

View file

@ -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