mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-07-26 12:08:15 +00:00
Fix security vulnerabilities and logic flaws
This commit is contained in:
+31
-6
@@ -11,11 +11,28 @@ let currentTabId = null;
|
||||
let currentTabTitle = null; // New: for Smart Matching
|
||||
let logs = [];
|
||||
let history = []; // New: for Action History
|
||||
let storageInitialized = false;
|
||||
let pendingLogs = [];
|
||||
let pendingHistory = [];
|
||||
|
||||
// Restore state from session storage
|
||||
chrome.storage.session.get(['logs', 'history'], (data) => {
|
||||
if (data.logs) logs = data.logs;
|
||||
if (data.history) history = data.history;
|
||||
storageInitialized = true;
|
||||
|
||||
if (pendingLogs.length > 0) {
|
||||
logs.unshift(...pendingLogs);
|
||||
if (logs.length > 50) logs = logs.slice(0, 50);
|
||||
chrome.storage.session.set({ logs });
|
||||
pendingLogs = [];
|
||||
}
|
||||
if (pendingHistory.length > 0) {
|
||||
history.unshift(...pendingHistory);
|
||||
if (history.length > 20) history = history.slice(0, 20);
|
||||
chrome.storage.session.set({ history });
|
||||
pendingHistory = [];
|
||||
}
|
||||
});
|
||||
|
||||
let reconnectTimer = null;
|
||||
@@ -56,9 +73,13 @@ function addLog(message, type = 'info') {
|
||||
message,
|
||||
type
|
||||
};
|
||||
logs.unshift(log);
|
||||
if (logs.length > 50) logs.pop();
|
||||
chrome.storage.session.set({ logs });
|
||||
if (!storageInitialized) {
|
||||
pendingLogs.unshift(log);
|
||||
} else {
|
||||
logs.unshift(log);
|
||||
if (logs.length > 50) logs.pop();
|
||||
chrome.storage.session.set({ logs });
|
||||
}
|
||||
chrome.runtime.sendMessage({ type: 'LOG_UPDATE', log }).catch(() => {});
|
||||
}
|
||||
|
||||
@@ -260,9 +281,13 @@ function addToHistory(action, senderId) {
|
||||
senderId: senderId || 'You',
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
history.unshift(historyEntry);
|
||||
if (history.length > 20) history.pop();
|
||||
chrome.storage.session.set({ history });
|
||||
if (!storageInitialized) {
|
||||
pendingHistory.unshift(historyEntry);
|
||||
} else {
|
||||
history.unshift(historyEntry);
|
||||
if (history.length > 20) history.pop();
|
||||
chrome.storage.session.set({ history });
|
||||
}
|
||||
chrome.runtime.sendMessage({ type: 'HISTORY_UPDATE', history }).catch(() => {});
|
||||
}
|
||||
|
||||
|
||||
+27
-15
@@ -7,7 +7,7 @@
|
||||
if (window.koalaSyncInjected) return;
|
||||
window.koalaSyncInjected = true;
|
||||
|
||||
let isProcessingCommand = false;
|
||||
let processingCommandUntil = 0;
|
||||
|
||||
// --- Helper: find the best video element on the page ---
|
||||
function findVideo() {
|
||||
@@ -20,7 +20,7 @@
|
||||
const video = findVideo();
|
||||
if (!video) return;
|
||||
|
||||
isProcessingCommand = true;
|
||||
processingCommandUntil = Date.now() + 1000;
|
||||
try {
|
||||
const host = window.location.hostname.toLowerCase();
|
||||
const isYouTube = host.includes('youtube.com');
|
||||
@@ -60,9 +60,6 @@
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('KoalaSync Media Action Error:', e);
|
||||
} finally {
|
||||
// Guarantee reset even on early returns in YouTube/Twitch blocks
|
||||
setTimeout(() => { isProcessingCommand = false; }, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +88,12 @@
|
||||
|
||||
// Listen for commands from background.js
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === 'get_current_time') {
|
||||
const video = findVideo();
|
||||
sendResponse({ currentTime: video ? video.currentTime : undefined });
|
||||
return true;
|
||||
}
|
||||
|
||||
if (message.type === 'SERVER_COMMAND') {
|
||||
const { action, payload } = message;
|
||||
|
||||
@@ -101,17 +104,17 @@
|
||||
} else if (action === 'seek') {
|
||||
tryMediaAction('seek', payload);
|
||||
} else if (action === 'force_sync_prepare') {
|
||||
isProcessingCommand = true;
|
||||
processingCommandUntil = Date.now() + 10000;
|
||||
const video = findVideo();
|
||||
if (video) {
|
||||
video.pause();
|
||||
video.currentTime = payload.targetTime;
|
||||
pollSeekReady(payload.targetTime).then(() => {
|
||||
chrome.runtime.sendMessage({ type: 'FORCE_SYNC_ACK' });
|
||||
setTimeout(() => { isProcessingCommand = false; }, 1000);
|
||||
processingCommandUntil = Date.now() + 1000;
|
||||
});
|
||||
} else {
|
||||
isProcessingCommand = false;
|
||||
processingCommandUntil = 0;
|
||||
}
|
||||
} else if (action === 'force_sync_execute') {
|
||||
tryMediaAction('play');
|
||||
@@ -121,7 +124,7 @@
|
||||
|
||||
// Detect native events
|
||||
function reportEvent(action) {
|
||||
if (isProcessingCommand) return;
|
||||
if (Date.now() < processingCommandUntil) return;
|
||||
const video = findVideo();
|
||||
if (!video) return;
|
||||
|
||||
@@ -147,15 +150,24 @@
|
||||
|
||||
// SPA Navigation Handler (MutationObserver)
|
||||
let lastMutate = 0;
|
||||
let observerTimeout = null;
|
||||
|
||||
function checkVideo() {
|
||||
lastMutate = Date.now();
|
||||
const video = findVideo();
|
||||
if (video && !video.dataset.koalaAttached) {
|
||||
console.log('KoalaSync: New video detected via navigation.');
|
||||
setupListeners();
|
||||
}
|
||||
}
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
const now = Date.now();
|
||||
if (now - lastMutate >= 1000) {
|
||||
lastMutate = now;
|
||||
const video = findVideo();
|
||||
if (video && !video.dataset.koalaAttached) {
|
||||
console.log('KoalaSync: New video detected via navigation.');
|
||||
setupListeners();
|
||||
}
|
||||
checkVideo();
|
||||
} else {
|
||||
if (observerTimeout) clearTimeout(observerTimeout);
|
||||
observerTimeout = setTimeout(checkVideo, 1000 - (now - lastMutate));
|
||||
}
|
||||
});
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
|
||||
+9
-6
@@ -337,12 +337,15 @@ function showError(msg) {
|
||||
elements.password.style.borderColor = 'var(--error)';
|
||||
|
||||
// Shake effect
|
||||
document.getElementById('tab-room').animate([
|
||||
{ transform: 'translateX(0)' },
|
||||
{ transform: 'translateX(-5px)' },
|
||||
{ transform: 'translateX(5px)' },
|
||||
{ transform: 'translateX(0)' }
|
||||
], { duration: 200, iterations: 2 });
|
||||
const activeTab = document.querySelector('.tab-content.active');
|
||||
if (activeTab) {
|
||||
activeTab.animate([
|
||||
{ transform: 'translateX(0)' },
|
||||
{ transform: 'translateX(-5px)' },
|
||||
{ transform: 'translateX(5px)' },
|
||||
{ transform: 'translateX(0)' }
|
||||
], { duration: 200, iterations: 2 });
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (elements.roomError) elements.roomError.style.display = 'none';
|
||||
|
||||
@@ -84,6 +84,16 @@ setInterval(() => {
|
||||
|
||||
const eventCounts = new Map(); // socketId -> { count, resetTime }
|
||||
|
||||
// Clean up connection counts to prevent memory leak
|
||||
setInterval(() => {
|
||||
const now = Date.now();
|
||||
for (const [ip, entry] of connectionCounts.entries()) {
|
||||
if (now > entry.resetTime) {
|
||||
connectionCounts.delete(ip);
|
||||
}
|
||||
}
|
||||
}, 60000);
|
||||
|
||||
function checkConnectionRate(ip) {
|
||||
const now = Date.now();
|
||||
const entry = connectionCounts.get(ip) || { count: 0, resetTime: now + 60000 };
|
||||
@@ -150,6 +160,9 @@ io.on('connection', (socket) => {
|
||||
|
||||
// Cleanup old room if re-joining
|
||||
const oldMapping = socketToRoom.get(socket.id);
|
||||
if (oldMapping && oldMapping.roomId === roomId) {
|
||||
return; // Already in this room, ignore to prevent spam
|
||||
}
|
||||
if (oldMapping && oldMapping.roomId !== roomId) {
|
||||
socket.leave(oldMapping.roomId);
|
||||
const oldRoom = rooms.get(oldMapping.roomId);
|
||||
@@ -232,6 +245,8 @@ io.on('connection', (socket) => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data || typeof data !== 'object') return; // Prevent null/invalid payload crash
|
||||
|
||||
const mapping = socketToRoom.get(socket.id);
|
||||
if (mapping) {
|
||||
const room = rooms.get(mapping.roomId);
|
||||
|
||||
Reference in New Issue
Block a user