Use index-based unique identifiers for download client selection to prevent cross-selection
Build and Push Docker Image / build (push) Successful in 28s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 58s
CI / Security audit (push) Successful in 1m19s
CI / Tests & coverage (push) Successful in 1m32s

This commit is contained in:
2026-05-19 23:56:05 +01:00
parent 544c168b82
commit 1ab7e52167
+21 -6
View File
@@ -386,7 +386,9 @@ function renderDownloads() {
// Filter downloads by selected clients // Filter downloads by selected clients
let filteredDownloads = downloads; let filteredDownloads = downloads;
if (selectedDownloadClients.length > 0) { if (selectedDownloadClients.length > 0) {
filteredDownloads = downloads.filter(d => selectedDownloadClients.includes(d.instanceId)); // Map indices to instanceIds
const selectedInstanceIds = selectedDownloadClients.map(idx => downloadClients[idx]?.id).filter(Boolean);
filteredDownloads = downloads.filter(d => selectedInstanceIds.includes(d.instanceId));
} }
// Sort downloads by client order (matching the order in downloadClients) // Sort downloads by client order (matching the order in downloadClients)
@@ -1109,7 +1111,7 @@ function initDownloadClientFilter() {
if (selectAllBtn) { if (selectAllBtn) {
selectAllBtn.addEventListener('click', (e) => { selectAllBtn.addEventListener('click', (e) => {
e.stopPropagation(); e.stopPropagation();
selectedDownloadClients = downloadClients.map(c => c.id); selectedDownloadClients = downloadClients.map((_, idx) => idx);
localStorage.setItem('sofarr-download-clients', JSON.stringify(selectedDownloadClients)); localStorage.setItem('sofarr-download-clients', JSON.stringify(selectedDownloadClients));
updateDownloadClientFilter(); updateDownloadClientFilter();
renderDownloads(); renderDownloads();
@@ -1139,6 +1141,19 @@ function updateDownloadClientFilter() {
return; return;
} }
// Migrate old client.id values to indices
if (selectedDownloadClients.length > 0 && typeof selectedDownloadClients[0] === 'string') {
const migratedIndices = [];
selectedDownloadClients.forEach(clientId => {
const index = downloadClients.findIndex(c => c.id === clientId);
if (index !== -1) {
migratedIndices.push(index);
}
});
selectedDownloadClients = migratedIndices;
localStorage.setItem('sofarr-download-clients', JSON.stringify(selectedDownloadClients));
}
// Add checkboxes for each download client // Add checkboxes for each download client
downloadClients.forEach((client, index) => { downloadClients.forEach((client, index) => {
const option = document.createElement('div'); const option = document.createElement('div');
@@ -1148,13 +1163,13 @@ function updateDownloadClientFilter() {
const checkbox = document.createElement('input'); const checkbox = document.createElement('input');
checkbox.type = 'checkbox'; checkbox.type = 'checkbox';
checkbox.className = 'download-client-checkbox'; checkbox.className = 'download-client-checkbox';
checkbox.value = client.id; checkbox.value = index; // Use index as unique identifier
checkbox.checked = selectedDownloadClients.includes(client.id); checkbox.checked = selectedDownloadClients.includes(index);
checkbox.id = checkboxId; checkbox.id = checkboxId;
// Toggle selection when checkbox changes // Toggle selection when checkbox changes
checkbox.addEventListener('change', (e) => { checkbox.addEventListener('change', (e) => {
toggleClientSelection(client.id, e.target.checked); toggleClientSelection(index, e.target.checked);
}); });
const label = document.createElement('label'); const label = document.createElement('label');
@@ -1197,7 +1212,7 @@ function updateSelectedCountDisplay() {
if (selectedDownloadClients.length === 0) { if (selectedDownloadClients.length === 0) {
selectedText.textContent = 'All clients'; selectedText.textContent = 'All clients';
} else if (selectedDownloadClients.length === 1) { } else if (selectedDownloadClients.length === 1) {
const client = downloadClients.find(c => c.id === selectedDownloadClients[0]); const client = downloadClients[selectedDownloadClients[0]];
selectedText.textContent = client ? client.name : '1 selected'; selectedText.textContent = client ? client.name : '1 selected';
} else { } else {
selectedText.textContent = `${selectedDownloadClients.length} selected`; selectedText.textContent = `${selectedDownloadClients.length} selected`;