From 26ad852451e29b83d29b60d02ad3fde0861fc5b4 Mon Sep 17 00:00:00 2001 From: Hosteroid Date: Sat, 11 Oct 2025 21:22:39 +0300 Subject: [PATCH] Fix bulk actions selection and set timezone earlier Improves bulk actions in the domains view by ensuring unique domain IDs are counted and selected, preventing double-counting from desktop and mobile checkboxes. Adds CSRF token to bulk actions forms for security. Moves timezone initialization to public/index.php to ensure it is set before any date operations, and updates base layout to reflect this change. --- app/Views/domains/index.php | 34 ++++++++++++++++++++++++++++------ app/Views/layout/base.php | 3 +-- public/index.php | 15 +++++++++++++++ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/app/Views/domains/index.php b/app/Views/domains/index.php index fe8d124..786eec1 100644 --- a/app/Views/domains/index.php +++ b/app/Views/domains/index.php @@ -452,20 +452,26 @@ function updateBulkActions() { const selectedCount = document.getElementById('selected-count'); const selectAllCheckbox = document.getElementById('select-all'); - if (checkboxes.length > 0) { + // Get unique domain IDs (avoid counting both desktop and mobile checkboxes) + const uniqueIds = new Set(Array.from(checkboxes).map(cb => cb.value)); + const count = uniqueIds.size; + + if (count > 0) { bulkActions.classList.remove('hidden'); bulkActions.classList.add('flex'); - selectedCount.textContent = `${checkboxes.length} domain(s) selected`; + selectedCount.textContent = `${count} domain(s) selected`; } else { bulkActions.classList.add('hidden'); bulkActions.classList.remove('flex'); } // Update select all checkbox state - const allCheckboxes = document.querySelectorAll('.domain-checkbox, .domain-checkbox-mobile'); + // Only count desktop checkboxes to avoid double counting + const allCheckboxes = document.querySelectorAll('.domain-checkbox'); + const checkedDesktopBoxes = document.querySelectorAll('.domain-checkbox:checked'); if (selectAllCheckbox) { - selectAllCheckbox.checked = allCheckboxes.length > 0 && checkboxes.length === allCheckboxes.length; - selectAllCheckbox.indeterminate = checkboxes.length > 0 && checkboxes.length < allCheckboxes.length; + selectAllCheckbox.checked = allCheckboxes.length > 0 && checkedDesktopBoxes.length === allCheckboxes.length; + selectAllCheckbox.indeterminate = checkedDesktopBoxes.length > 0 && checkedDesktopBoxes.length < allCheckboxes.length; } } @@ -480,7 +486,9 @@ function clearSelection() { function getSelectedIds() { const checkboxes = document.querySelectorAll('.domain-checkbox:checked, .domain-checkbox-mobile:checked'); - return Array.from(checkboxes).map(cb => cb.value); + // Return unique IDs only (avoid duplicates from desktop and mobile views) + const ids = Array.from(checkboxes).map(cb => cb.value); + return [...new Set(ids)]; } function bulkRefresh() { @@ -491,6 +499,13 @@ function bulkRefresh() { form.method = 'POST'; form.action = '/domains/bulk-refresh'; + // Add CSRF token + const csrfInput = document.createElement('input'); + csrfInput.type = 'hidden'; + csrfInput.name = 'csrf_token'; + csrfInput.value = ''; + form.appendChild(csrfInput); + ids.forEach(id => { const input = document.createElement('input'); input.type = 'hidden'; @@ -515,6 +530,13 @@ function bulkDelete() { form.method = 'POST'; form.action = '/domains/bulk-delete'; + // Add CSRF token + const csrfInput = document.createElement('input'); + csrfInput.type = 'hidden'; + csrfInput.name = 'csrf_token'; + csrfInput.value = ''; + form.appendChild(csrfInput); + ids.forEach(id => { const input = document.createElement('input'); input.type = 'hidden'; diff --git a/app/Views/layout/base.php b/app/Views/layout/base.php index 870ff47..82f3294 100644 --- a/app/Views/layout/base.php +++ b/app/Views/layout/base.php @@ -26,8 +26,7 @@ if (!isset($appName)) { $appTimezone = $appSettings['app_timezone']; $appVersion = $appSettings['app_version']; - // Set PHP timezone - date_default_timezone_set($appTimezone); + // Note: Timezone is now set early in public/index.php (before controllers run) } ?> diff --git a/public/index.php b/public/index.php index ef04fe5..819ca54 100644 --- a/public/index.php +++ b/public/index.php @@ -58,6 +58,21 @@ if (!isset($_SESSION['user_id']) && isset($_COOKIE['remember_token']) && !$isIns $authController->checkRememberToken(); } +// Set application timezone early (before any date operations) +if (!$isInstallerPath && file_exists($installedFlagFile)) { + try { + $settingModel = new \App\Models\Setting(); + $timezone = $settingModel->getValue('app_timezone', 'UTC'); + date_default_timezone_set($timezone); + } catch (\Exception $e) { + // Database not available, use UTC as fallback + date_default_timezone_set('UTC'); + } +} else { + // Default to UTC during installation + date_default_timezone_set('UTC'); +} + // Initialize application $app = new Application();