fix(extension,server): resolve 12 audit findings (lobby cleanup, dedup race, protocol version, rate limiting, observer scope, and more)

This commit is contained in:
Timo
2026-05-25 02:11:54 +02:00
parent bf0fa55b9d
commit 385602c194
4 changed files with 47 additions and 21 deletions
+8 -3
View File
@@ -360,6 +360,9 @@ async function connect() {
forceSyncAcks: [],
forceSyncDeadline: null
});
// Cancel any active episode lobby
clearEpisodeLobbyState();
if (currentRoom) {
currentRoom.peers = [];
@@ -412,6 +415,7 @@ function showNotification(senderName, action) {
const label = action === 'play' ? 'started playback' :
action === 'pause' ? 'paused playback' :
action === 'seek' ? 'seeked the video' :
action === 'force_sync_prepare' ? 'started force sync' :
action === 'force_sync_execute' ? 'synchronized everyone' : action;
// Find username in current room if available
@@ -954,6 +958,9 @@ function leaveOldRoomIfSwitching(newRoomId) {
forceSyncAcks: [],
forceSyncDeadline: null
});
// Cancel any active episode lobby
clearEpisodeLobbyState();
}
}
@@ -1051,9 +1058,7 @@ async function handleAsyncMessage(message, sender, sendResponse) {
} else if (message.type === 'GET_HISTORY') {
sendResponse(history);
} else if (message.type === 'GET_ROOM_LIST') {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(`42${JSON.stringify([EVENTS.GET_ROOMS])}`);
}
emit(EVENTS.GET_ROOMS, {});
sendResponse({ status: 'ok' });
} else if (message.type === 'WEB_JOIN_REQUEST') {
const { roomId, password, useCustomServer, serverUrl } = message;
+1 -1
View File
@@ -519,7 +519,7 @@
observerTimeout = setTimeout(checkVideo, 1000 - (now - lastMutate));
}
});
observer.observe(document.body, { childList: true, subtree: true });
observer.observe(document.documentElement, { childList: true, subtree: true });
// --- SHARED_HEARTBEAT_INJECT_START ---
const HEARTBEAT_INTERVAL_VAL = 15000;
+17 -2
View File
@@ -231,6 +231,13 @@ function getVolumeIcon(volume, muted) {
let activePeers = [];
let interpolationInterval = null;
function stopInterpolation() {
if (interpolationInterval) {
clearInterval(interpolationInterval);
interpolationInterval = null;
}
}
function startInterpolation() {
if (interpolationInterval) return;
interpolationInterval = setInterval(() => {
@@ -249,7 +256,11 @@ function startInterpolation() {
function updatePeerList(peers) {
if (!peers) return;
activePeers = peers;
if (!interpolationInterval) startInterpolation();
if (peers.length === 0) {
stopInterpolation();
} else if (!interpolationInterval) {
startInterpolation();
}
// UI Throttle: Only re-render if the peer state actually changed (excluding time interpolation)
const stateToHash = peers.map(p => ({
@@ -793,6 +804,10 @@ elements.forceSyncBtn.addEventListener('click', async () => {
let targetTime = null;
if (mode === 'jump-to-others') {
if (!localPeerId) {
showError('Identity not yet loaded. Wait a moment and try again.');
return;
}
const peers = status.peers || [];
const otherTimes = peers
.filter(p => typeof p === 'object' && p.peerId !== localPeerId && p.currentTime != null && !isNaN(p.currentTime))
@@ -888,7 +903,7 @@ async function refreshLogs() {
logs.forEach(log => {
const entry = document.createElement('div');
entry.className = `log-entry log-${log.type}`;
const timeStr = log.timestamp.split('T')[1].split('.')[0];
const timeStr = log.timestamp?.split('T')?.[1]?.split('.')[0] || '?';
entry.textContent = `[${timeStr}] ${log.message}`;
elements.logList.appendChild(entry);
});