2025-10-08 18:54:34 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Controllers;
|
|
|
|
|
|
|
|
|
|
use Core\Controller;
|
2025-10-10 14:01:19 +03:00
|
|
|
use Core\Auth;
|
2025-10-08 18:54:34 +03:00
|
|
|
use App\Models\Setting;
|
2025-10-14 00:27:50 +03:00
|
|
|
use App\Helpers\EmailHelper;
|
|
|
|
|
use App\Services\Logger;
|
2025-10-08 18:54:34 +03:00
|
|
|
|
|
|
|
|
class SettingsController extends Controller
|
|
|
|
|
{
|
|
|
|
|
private Setting $settingModel;
|
2025-10-14 00:27:50 +03:00
|
|
|
private Logger $logger;
|
2025-10-08 18:54:34 +03:00
|
|
|
|
|
|
|
|
public function __construct()
|
|
|
|
|
{
|
2025-10-10 14:01:19 +03:00
|
|
|
Auth::requireAdmin();
|
2025-10-08 18:54:34 +03:00
|
|
|
$this->settingModel = new Setting();
|
2025-10-14 00:27:50 +03:00
|
|
|
$this->logger = new Logger('settings');
|
2025-10-08 18:54:34 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function index()
|
|
|
|
|
{
|
|
|
|
|
$settings = $this->settingModel->getAllAsKeyValue();
|
|
|
|
|
$appSettings = $this->settingModel->getAppSettings();
|
|
|
|
|
$emailSettings = $this->settingModel->getEmailSettings();
|
Add CSRF, CAPTCHA, and input validation improvements
Introduces CSRF protection to all sensitive controller actions, integrates configurable CAPTCHA (reCAPTCHA v2/v3, Turnstile) for authentication and registration flows, and centralizes input validation via a new InputValidator helper. Adds new helpers and services for CSRF and CAPTCHA, updates settings and migration for CAPTCHA configuration, and enhances logging and error handling in TLD registry import processes. Also improves validation for user, domain, group, and profile inputs throughout the application.
2025-10-10 00:04:12 +03:00
|
|
|
$captchaSettings = $this->settingModel->getCaptchaSettings();
|
Add two-factor authentication (2FA) support
Introduces two-factor authentication (2FA) with TOTP, backup codes, and email codes. Adds controllers, services, views, and migration for 2FA setup, verification, and management. Updates user and settings models, email helper, and relevant controllers to support 2FA policy enforcement, configuration, and user flows. Enhances security by allowing admins to require or disable 2FA, and provides backup code generation and management for account recovery.
2025-10-16 17:25:06 +03:00
|
|
|
$twoFactorSettings = $this->settingModel->getTwoFactorSettings();
|
2025-10-08 18:54:34 +03:00
|
|
|
|
|
|
|
|
// Predefined notification day options
|
|
|
|
|
$notificationPresets = [
|
|
|
|
|
'minimal' => [
|
|
|
|
|
'label' => 'Minimal (30, 7, 1 days)',
|
|
|
|
|
'value' => '30,7,1'
|
|
|
|
|
],
|
|
|
|
|
'standard' => [
|
|
|
|
|
'label' => 'Standard (60, 30, 21, 14, 7, 5, 3, 2, 1 days)',
|
|
|
|
|
'value' => '60,30,21,14,7,5,3,2,1'
|
|
|
|
|
],
|
|
|
|
|
'frequent' => [
|
|
|
|
|
'label' => 'Frequent (90, 60, 45, 30, 21, 14, 10, 7, 5, 3, 2, 1 days)',
|
|
|
|
|
'value' => '90,60,45,30,21,14,10,7,5,3,2,1'
|
|
|
|
|
],
|
|
|
|
|
'business' => [
|
|
|
|
|
'label' => 'Business Focused (60, 30, 14, 7, 3, 1 days)',
|
|
|
|
|
'value' => '60,30,14,7,3,1'
|
|
|
|
|
],
|
|
|
|
|
'conservative' => [
|
|
|
|
|
'label' => 'Conservative (30, 15, 7, 3, 1 days)',
|
|
|
|
|
'value' => '30,15,7,3,1'
|
|
|
|
|
],
|
|
|
|
|
'custom' => [
|
|
|
|
|
'label' => 'Custom',
|
|
|
|
|
'value' => 'custom'
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Check interval presets
|
|
|
|
|
$checkIntervalPresets = [
|
|
|
|
|
['label' => 'Every 6 hours', 'value' => 6],
|
|
|
|
|
['label' => 'Every 12 hours', 'value' => 12],
|
|
|
|
|
['label' => 'Daily (24 hours)', 'value' => 24],
|
|
|
|
|
['label' => 'Every 2 days (48 hours)', 'value' => 48],
|
|
|
|
|
['label' => 'Weekly (168 hours)', 'value' => 168]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$this->view('settings/index', [
|
|
|
|
|
'settings' => $settings,
|
|
|
|
|
'appSettings' => $appSettings,
|
|
|
|
|
'emailSettings' => $emailSettings,
|
Add CSRF, CAPTCHA, and input validation improvements
Introduces CSRF protection to all sensitive controller actions, integrates configurable CAPTCHA (reCAPTCHA v2/v3, Turnstile) for authentication and registration flows, and centralizes input validation via a new InputValidator helper. Adds new helpers and services for CSRF and CAPTCHA, updates settings and migration for CAPTCHA configuration, and enhances logging and error handling in TLD registry import processes. Also improves validation for user, domain, group, and profile inputs throughout the application.
2025-10-10 00:04:12 +03:00
|
|
|
'captchaSettings' => $captchaSettings,
|
Add two-factor authentication (2FA) support
Introduces two-factor authentication (2FA) with TOTP, backup codes, and email codes. Adds controllers, services, views, and migration for 2FA setup, verification, and management. Updates user and settings models, email helper, and relevant controllers to support 2FA policy enforcement, configuration, and user flows. Enhances security by allowing admins to require or disable 2FA, and provides backup code generation and management for account recovery.
2025-10-16 17:25:06 +03:00
|
|
|
'twoFactorSettings' => $twoFactorSettings,
|
2025-10-08 18:54:34 +03:00
|
|
|
'notificationPresets' => $notificationPresets,
|
|
|
|
|
'checkIntervalPresets' => $checkIntervalPresets,
|
|
|
|
|
'title' => 'Settings'
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function update()
|
|
|
|
|
{
|
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
|
|
|
$this->redirect('/settings');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
Add CSRF, CAPTCHA, and input validation improvements
Introduces CSRF protection to all sensitive controller actions, integrates configurable CAPTCHA (reCAPTCHA v2/v3, Turnstile) for authentication and registration flows, and centralizes input validation via a new InputValidator helper. Adds new helpers and services for CSRF and CAPTCHA, updates settings and migration for CAPTCHA configuration, and enhances logging and error handling in TLD registry import processes. Also improves validation for user, domain, group, and profile inputs throughout the application.
2025-10-10 00:04:12 +03:00
|
|
|
// CSRF Protection
|
|
|
|
|
$this->verifyCsrf('/settings#monitoring');
|
|
|
|
|
|
2025-10-08 18:54:34 +03:00
|
|
|
try {
|
|
|
|
|
// Update notification days
|
|
|
|
|
$notificationPreset = $_POST['notification_preset'] ?? 'standard';
|
|
|
|
|
|
|
|
|
|
if ($notificationPreset === 'custom') {
|
|
|
|
|
// Custom days entered by user
|
|
|
|
|
$customDays = trim($_POST['custom_notification_days'] ?? '');
|
|
|
|
|
|
|
|
|
|
if (empty($customDays)) {
|
|
|
|
|
$_SESSION['error'] = 'Please enter notification days for custom preset';
|
|
|
|
|
$this->redirect('/settings#monitoring');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate custom days (comma-separated integers)
|
|
|
|
|
$daysArray = array_map('trim', explode(',', $customDays));
|
|
|
|
|
$daysArray = array_filter($daysArray, function($day) {
|
|
|
|
|
return is_numeric($day) && $day > 0;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (empty($daysArray)) {
|
|
|
|
|
$_SESSION['error'] = 'Invalid notification days format. Use comma-separated numbers (e.g., 30,15,7,1)';
|
|
|
|
|
$this->redirect('/settings#monitoring');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sort in descending order
|
|
|
|
|
rsort($daysArray, SORT_NUMERIC);
|
|
|
|
|
$notificationDays = implode(',', $daysArray);
|
|
|
|
|
} else {
|
|
|
|
|
// Use preset value
|
|
|
|
|
$notificationDays = $_POST['notification_days_before'] ?? '30,15,7,3,1';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update check interval
|
|
|
|
|
$checkInterval = (int)($_POST['check_interval_hours'] ?? 24);
|
|
|
|
|
|
|
|
|
|
if ($checkInterval < 1 || $checkInterval > 720) { // Max 30 days
|
|
|
|
|
$_SESSION['error'] = 'Check interval must be between 1 and 720 hours';
|
|
|
|
|
$this->redirect('/settings#monitoring');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Save settings
|
|
|
|
|
$this->settingModel->setValue('notification_days_before', $notificationDays);
|
|
|
|
|
$this->settingModel->setValue('check_interval_hours', $checkInterval);
|
|
|
|
|
|
|
|
|
|
$_SESSION['success'] = 'Settings updated successfully';
|
|
|
|
|
$this->redirect('/settings#monitoring');
|
|
|
|
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
$_SESSION['error'] = 'Failed to update settings: ' . $e->getMessage();
|
|
|
|
|
$this->redirect('/settings#monitoring');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testCron()
|
|
|
|
|
{
|
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
|
|
|
$this->redirect('/settings');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
Add CSRF, CAPTCHA, and input validation improvements
Introduces CSRF protection to all sensitive controller actions, integrates configurable CAPTCHA (reCAPTCHA v2/v3, Turnstile) for authentication and registration flows, and centralizes input validation via a new InputValidator helper. Adds new helpers and services for CSRF and CAPTCHA, updates settings and migration for CAPTCHA configuration, and enhances logging and error handling in TLD registry import processes. Also improves validation for user, domain, group, and profile inputs throughout the application.
2025-10-10 00:04:12 +03:00
|
|
|
// CSRF Protection
|
|
|
|
|
$this->verifyCsrf('/settings');
|
|
|
|
|
|
2025-10-08 18:54:34 +03:00
|
|
|
// Update last check run time to show the test worked
|
|
|
|
|
$this->settingModel->updateLastCheckRun();
|
|
|
|
|
|
|
|
|
|
$_SESSION['info'] = 'Test notification sent (feature coming soon). Last check time updated.';
|
|
|
|
|
$this->redirect('/settings');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function clearLogs()
|
|
|
|
|
{
|
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
|
|
|
$this->redirect('/settings');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
Add CSRF, CAPTCHA, and input validation improvements
Introduces CSRF protection to all sensitive controller actions, integrates configurable CAPTCHA (reCAPTCHA v2/v3, Turnstile) for authentication and registration flows, and centralizes input validation via a new InputValidator helper. Adds new helpers and services for CSRF and CAPTCHA, updates settings and migration for CAPTCHA configuration, and enhances logging and error handling in TLD registry import processes. Also improves validation for user, domain, group, and profile inputs throughout the application.
2025-10-10 00:04:12 +03:00
|
|
|
// CSRF Protection
|
|
|
|
|
$this->verifyCsrf('/settings#maintenance');
|
|
|
|
|
|
2025-10-08 18:54:34 +03:00
|
|
|
try {
|
|
|
|
|
// Clear notification logs older than 30 days
|
|
|
|
|
$stmt = $this->settingModel->db->prepare(
|
|
|
|
|
"DELETE FROM notification_logs WHERE sent_at < DATE_SUB(NOW(), INTERVAL 30 DAY)"
|
|
|
|
|
);
|
|
|
|
|
$stmt->execute();
|
|
|
|
|
$deleted = $stmt->rowCount();
|
|
|
|
|
|
|
|
|
|
$_SESSION['success'] = "Cleared $deleted old notification log(s)";
|
|
|
|
|
$this->redirect('/settings#maintenance');
|
|
|
|
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
$_SESSION['error'] = 'Failed to clear logs: ' . $e->getMessage();
|
|
|
|
|
$this->redirect('/settings#maintenance');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function updateApp()
|
|
|
|
|
{
|
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
|
|
|
$this->redirect('/settings');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
Add CSRF, CAPTCHA, and input validation improvements
Introduces CSRF protection to all sensitive controller actions, integrates configurable CAPTCHA (reCAPTCHA v2/v3, Turnstile) for authentication and registration flows, and centralizes input validation via a new InputValidator helper. Adds new helpers and services for CSRF and CAPTCHA, updates settings and migration for CAPTCHA configuration, and enhances logging and error handling in TLD registry import processes. Also improves validation for user, domain, group, and profile inputs throughout the application.
2025-10-10 00:04:12 +03:00
|
|
|
// CSRF Protection
|
|
|
|
|
$this->verifyCsrf('/settings#app');
|
|
|
|
|
|
2025-10-08 18:54:34 +03:00
|
|
|
try {
|
|
|
|
|
$appSettings = [
|
|
|
|
|
'app_name' => trim($_POST['app_name'] ?? 'Domain Monitor'),
|
|
|
|
|
'app_url' => trim($_POST['app_url'] ?? 'http://localhost:8000'),
|
|
|
|
|
'app_timezone' => trim($_POST['app_timezone'] ?? 'UTC')
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Validate app_name
|
|
|
|
|
if (empty($appSettings['app_name'])) {
|
|
|
|
|
$_SESSION['error'] = 'Application name is required';
|
|
|
|
|
$this->redirect('/settings#app');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate app_url
|
|
|
|
|
if (empty($appSettings['app_url']) || !filter_var($appSettings['app_url'], FILTER_VALIDATE_URL)) {
|
|
|
|
|
$_SESSION['error'] = 'Please enter a valid application URL';
|
|
|
|
|
$this->redirect('/settings#app');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate timezone
|
|
|
|
|
$validTimezones = timezone_identifiers_list();
|
|
|
|
|
if (!in_array($appSettings['app_timezone'], $validTimezones)) {
|
|
|
|
|
$_SESSION['error'] = 'Invalid timezone selected';
|
|
|
|
|
$this->redirect('/settings#app');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
Upgraded to 1.1.0
1.1.0 (2025-10-09)
- **User Notifications System** - In-app notification center with 7 notification types, filtering, pagination
- **Advanced Session Management** - Database-backed sessions with geolocation (country, city, ISP)
- **Remote Session Control** - Terminate any device instantly with immediate logout validation
- **Enhanced Profile Page** - Sidebar navigation with 4 tabs, hash-based routing (#profile, #security, #sessions)
- **MVC Architecture Refactoring** - 3 new Helpers (Layout, Domain, Session), ~265 lines cleaned from views
- **Geolocation Tracking** - IP-based location detection using ip-api.com, country flags with flag-icons
- **Device Detection** - Browser & device type parsing (Chrome/Firefox/Safari, Desktop/Mobile/Tablet)
- **Auto-Detected Cron Paths** - Settings show actual installation paths (thanks @jadeops)
- **Welcome Notifications** - Sent to new users on registration or fresh install
- **Upgrade Notifications** - Admins notified on system updates with version & migration count
- **Web-Based Installer** - Replaces CLI, auto-generates encryption key, one-time password display
- **Web-Based Updater** - `/install/update` for running new migrations with smart detection
- **User Registration** - Full signup flow with email verification, password reset, resend verification
- **User Management** - CRUD for users with filtering, sorting, pagination (admin-only)
- **Remember Me** - 30-day secure tokens linked to sessions, cascade deletion on logout
- **Session Validator** - Middleware validates sessions on every request for instant remote logout
- **Consistent UI/UX** - Unified filtering, sorting, pagination across Domains, Users, Notifications, TLD Registry
- **Smart Migrations** - Consolidated schema for fresh installs, incremental for upgrades
- **XSS Protection** - htmlspecialchars() applied across all user-facing data (thanks @jadeops)
2025-10-09 18:02:46 +03:00
|
|
|
// Update app settings
|
2025-10-08 18:54:34 +03:00
|
|
|
$this->settingModel->updateAppSettings($appSettings);
|
Upgraded to 1.1.0
1.1.0 (2025-10-09)
- **User Notifications System** - In-app notification center with 7 notification types, filtering, pagination
- **Advanced Session Management** - Database-backed sessions with geolocation (country, city, ISP)
- **Remote Session Control** - Terminate any device instantly with immediate logout validation
- **Enhanced Profile Page** - Sidebar navigation with 4 tabs, hash-based routing (#profile, #security, #sessions)
- **MVC Architecture Refactoring** - 3 new Helpers (Layout, Domain, Session), ~265 lines cleaned from views
- **Geolocation Tracking** - IP-based location detection using ip-api.com, country flags with flag-icons
- **Device Detection** - Browser & device type parsing (Chrome/Firefox/Safari, Desktop/Mobile/Tablet)
- **Auto-Detected Cron Paths** - Settings show actual installation paths (thanks @jadeops)
- **Welcome Notifications** - Sent to new users on registration or fresh install
- **Upgrade Notifications** - Admins notified on system updates with version & migration count
- **Web-Based Installer** - Replaces CLI, auto-generates encryption key, one-time password display
- **Web-Based Updater** - `/install/update` for running new migrations with smart detection
- **User Registration** - Full signup flow with email verification, password reset, resend verification
- **User Management** - CRUD for users with filtering, sorting, pagination (admin-only)
- **Remember Me** - 30-day secure tokens linked to sessions, cascade deletion on logout
- **Session Validator** - Middleware validates sessions on every request for instant remote logout
- **Consistent UI/UX** - Unified filtering, sorting, pagination across Domains, Users, Notifications, TLD Registry
- **Smart Migrations** - Consolidated schema for fresh installs, incremental for upgrades
- **XSS Protection** - htmlspecialchars() applied across all user-facing data (thanks @jadeops)
2025-10-09 18:02:46 +03:00
|
|
|
|
|
|
|
|
// Update registration settings
|
|
|
|
|
$registrationEnabled = isset($_POST['registration_enabled']) ? '1' : '0';
|
|
|
|
|
$requireEmailVerification = isset($_POST['require_email_verification']) ? '1' : '0';
|
|
|
|
|
|
|
|
|
|
$this->settingModel->setValue('registration_enabled', $registrationEnabled);
|
|
|
|
|
$this->settingModel->setValue('require_email_verification', $requireEmailVerification);
|
|
|
|
|
|
2025-10-08 18:54:34 +03:00
|
|
|
$_SESSION['success'] = 'Application settings updated successfully';
|
|
|
|
|
$this->redirect('/settings#app');
|
|
|
|
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
$_SESSION['error'] = 'Failed to update application settings: ' . $e->getMessage();
|
|
|
|
|
$this->redirect('/settings#app');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function updateEmail()
|
|
|
|
|
{
|
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
|
|
|
$this->redirect('/settings');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
Add CSRF, CAPTCHA, and input validation improvements
Introduces CSRF protection to all sensitive controller actions, integrates configurable CAPTCHA (reCAPTCHA v2/v3, Turnstile) for authentication and registration flows, and centralizes input validation via a new InputValidator helper. Adds new helpers and services for CSRF and CAPTCHA, updates settings and migration for CAPTCHA configuration, and enhances logging and error handling in TLD registry import processes. Also improves validation for user, domain, group, and profile inputs throughout the application.
2025-10-10 00:04:12 +03:00
|
|
|
// CSRF Protection
|
|
|
|
|
$this->verifyCsrf('/settings#email');
|
|
|
|
|
|
2025-10-08 18:54:34 +03:00
|
|
|
try {
|
2025-10-14 00:27:50 +03:00
|
|
|
$port = (int)trim($_POST['mail_port'] ?? '2525');
|
|
|
|
|
$encryption = trim($_POST['mail_encryption'] ?? 'tls');
|
|
|
|
|
|
|
|
|
|
// Auto-detect encryption based on port if not explicitly set
|
|
|
|
|
$originalEncryption = $encryption;
|
|
|
|
|
if (empty($encryption) || $encryption === 'tls') {
|
|
|
|
|
if ($port === 465) {
|
|
|
|
|
$encryption = 'ssl'; // Port 465 should use SSL
|
|
|
|
|
$this->logger->info('Auto-detected SSL encryption for port 465', [
|
|
|
|
|
'port' => $port,
|
|
|
|
|
'original_encryption' => $originalEncryption,
|
|
|
|
|
'detected_encryption' => $encryption
|
|
|
|
|
]);
|
|
|
|
|
} elseif ($port === 587) {
|
|
|
|
|
$encryption = 'tls'; // Port 587 should use TLS
|
|
|
|
|
$this->logger->info('Auto-detected TLS encryption for port 587', [
|
|
|
|
|
'port' => $port,
|
|
|
|
|
'original_encryption' => $originalEncryption,
|
|
|
|
|
'detected_encryption' => $encryption
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
// For other ports, keep the user's selection
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-08 18:54:34 +03:00
|
|
|
$emailSettings = [
|
|
|
|
|
'mail_host' => trim($_POST['mail_host'] ?? ''),
|
2025-10-14 00:27:50 +03:00
|
|
|
'mail_port' => $port,
|
2025-10-08 18:54:34 +03:00
|
|
|
'mail_username' => trim($_POST['mail_username'] ?? ''),
|
|
|
|
|
'mail_password' => trim($_POST['mail_password'] ?? ''),
|
2025-10-14 00:27:50 +03:00
|
|
|
'mail_encryption' => $encryption,
|
2025-10-08 18:54:34 +03:00
|
|
|
'mail_from_address' => trim($_POST['mail_from_address'] ?? ''),
|
|
|
|
|
'mail_from_name' => trim($_POST['mail_from_name'] ?? 'Domain Monitor')
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Validate required fields
|
|
|
|
|
if (empty($emailSettings['mail_host'])) {
|
|
|
|
|
$_SESSION['error'] = 'Mail host is required';
|
|
|
|
|
$this->redirect('/settings#email');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (empty($emailSettings['mail_from_address']) || !filter_var($emailSettings['mail_from_address'], FILTER_VALIDATE_EMAIL)) {
|
|
|
|
|
$_SESSION['error'] = 'Please enter a valid from email address';
|
|
|
|
|
$this->redirect('/settings#email');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate port
|
|
|
|
|
if (!is_numeric($emailSettings['mail_port']) || $emailSettings['mail_port'] < 1 || $emailSettings['mail_port'] > 65535) {
|
|
|
|
|
$_SESSION['error'] = 'Please enter a valid port number (1-65535)';
|
|
|
|
|
$this->redirect('/settings#email');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->settingModel->updateEmailSettings($emailSettings);
|
|
|
|
|
$_SESSION['success'] = 'Email settings updated successfully';
|
|
|
|
|
$this->redirect('/settings#email');
|
|
|
|
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
$_SESSION['error'] = 'Failed to update email settings: ' . $e->getMessage();
|
|
|
|
|
$this->redirect('/settings#email');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Add CSRF, CAPTCHA, and input validation improvements
Introduces CSRF protection to all sensitive controller actions, integrates configurable CAPTCHA (reCAPTCHA v2/v3, Turnstile) for authentication and registration flows, and centralizes input validation via a new InputValidator helper. Adds new helpers and services for CSRF and CAPTCHA, updates settings and migration for CAPTCHA configuration, and enhances logging and error handling in TLD registry import processes. Also improves validation for user, domain, group, and profile inputs throughout the application.
2025-10-10 00:04:12 +03:00
|
|
|
public function updateCaptcha()
|
|
|
|
|
{
|
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
|
|
|
$this->redirect('/settings');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CSRF Protection
|
|
|
|
|
$this->verifyCsrf('/settings#security');
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$captchaProvider = trim($_POST['captcha_provider'] ?? 'disabled');
|
|
|
|
|
$captchaSiteKey = trim($_POST['captcha_site_key'] ?? '');
|
|
|
|
|
$captchaSecretKey = trim($_POST['captcha_secret_key'] ?? '');
|
|
|
|
|
$recaptchaV3Threshold = trim($_POST['recaptcha_v3_score_threshold'] ?? '0.5');
|
|
|
|
|
|
|
|
|
|
// Validate provider
|
|
|
|
|
$validProviders = ['disabled', 'recaptcha_v2', 'recaptcha_v3', 'turnstile'];
|
|
|
|
|
if (!in_array($captchaProvider, $validProviders)) {
|
|
|
|
|
$_SESSION['error'] = 'Invalid CAPTCHA provider selected';
|
|
|
|
|
$this->redirect('/settings#security');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If CAPTCHA is enabled, validate keys
|
|
|
|
|
if ($captchaProvider !== 'disabled') {
|
|
|
|
|
if (empty($captchaSiteKey)) {
|
|
|
|
|
$_SESSION['error'] = 'Site key is required when CAPTCHA is enabled';
|
|
|
|
|
$this->redirect('/settings#security');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (empty($captchaSecretKey)) {
|
|
|
|
|
$_SESSION['error'] = 'Secret key is required when CAPTCHA is enabled';
|
|
|
|
|
$this->redirect('/settings#security');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate v3 score threshold
|
|
|
|
|
if ($captchaProvider === 'recaptcha_v3') {
|
|
|
|
|
$threshold = floatval($recaptchaV3Threshold);
|
|
|
|
|
if ($threshold < 0.0 || $threshold > 1.0) {
|
|
|
|
|
$_SESSION['error'] = 'reCAPTCHA v3 score threshold must be between 0.0 and 1.0';
|
|
|
|
|
$this->redirect('/settings#security');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Prepare settings array
|
|
|
|
|
$captchaSettings = [
|
|
|
|
|
'captcha_provider' => $captchaProvider,
|
|
|
|
|
'captcha_site_key' => $captchaSiteKey,
|
|
|
|
|
'recaptcha_v3_score_threshold' => $recaptchaV3Threshold
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Only update secret key if provided (to allow updating other settings without re-entering secret)
|
|
|
|
|
if (!empty($captchaSecretKey)) {
|
|
|
|
|
$captchaSettings['captcha_secret_key'] = $captchaSecretKey;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update CAPTCHA settings
|
|
|
|
|
$this->settingModel->updateCaptchaSettings($captchaSettings);
|
|
|
|
|
|
|
|
|
|
$_SESSION['success'] = 'CAPTCHA settings updated successfully';
|
|
|
|
|
$this->redirect('/settings#security');
|
|
|
|
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
$_SESSION['error'] = 'Failed to update CAPTCHA settings: ' . $e->getMessage();
|
|
|
|
|
$this->redirect('/settings#security');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-08 18:54:34 +03:00
|
|
|
public function testEmail()
|
|
|
|
|
{
|
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
|
|
|
$this->redirect('/settings');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
Add CSRF, CAPTCHA, and input validation improvements
Introduces CSRF protection to all sensitive controller actions, integrates configurable CAPTCHA (reCAPTCHA v2/v3, Turnstile) for authentication and registration flows, and centralizes input validation via a new InputValidator helper. Adds new helpers and services for CSRF and CAPTCHA, updates settings and migration for CAPTCHA configuration, and enhances logging and error handling in TLD registry import processes. Also improves validation for user, domain, group, and profile inputs throughout the application.
2025-10-10 00:04:12 +03:00
|
|
|
// CSRF Protection
|
|
|
|
|
$this->verifyCsrf('/settings#email');
|
|
|
|
|
|
2025-10-08 18:54:34 +03:00
|
|
|
$testEmail = trim($_POST['test_email'] ?? '');
|
|
|
|
|
|
|
|
|
|
if (empty($testEmail) || !filter_var($testEmail, FILTER_VALIDATE_EMAIL)) {
|
|
|
|
|
$_SESSION['error'] = 'Please enter a valid email address';
|
|
|
|
|
$this->redirect('/settings#email');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-14 00:27:50 +03:00
|
|
|
// Use EmailHelper to send test email
|
|
|
|
|
$result = EmailHelper::sendTestEmail($testEmail);
|
|
|
|
|
|
|
|
|
|
if ($result['success']) {
|
|
|
|
|
$_SESSION['success'] = $result['message'];
|
|
|
|
|
$this->logger->info('Test email sent successfully', [
|
|
|
|
|
'email' => $testEmail
|
|
|
|
|
]);
|
|
|
|
|
} else {
|
|
|
|
|
// Log detailed error information for debugging
|
|
|
|
|
$this->logger->error('Test email failed', [
|
|
|
|
|
'email' => $testEmail,
|
|
|
|
|
'debug_info' => $result['debug_info'] ?? null,
|
|
|
|
|
'error' => $result['error'] ?? null
|
|
|
|
|
]);
|
2025-10-08 18:54:34 +03:00
|
|
|
|
2025-10-14 00:27:50 +03:00
|
|
|
$_SESSION['error'] = $result['message'];
|
2025-10-08 18:54:34 +03:00
|
|
|
|
2025-10-14 00:27:50 +03:00
|
|
|
// In development, show more detailed error
|
|
|
|
|
if (($_ENV['APP_ENV'] ?? 'production') === 'development') {
|
|
|
|
|
$_SESSION['error'] .= " (Debug: " . ($result['debug_info'] ?? $result['error']) . ")";
|
|
|
|
|
}
|
2025-10-08 18:54:34 +03:00
|
|
|
}
|
2025-10-14 00:27:50 +03:00
|
|
|
|
|
|
|
|
$this->redirect('/settings#email');
|
2025-10-08 18:54:34 +03:00
|
|
|
}
|
Add two-factor authentication (2FA) support
Introduces two-factor authentication (2FA) with TOTP, backup codes, and email codes. Adds controllers, services, views, and migration for 2FA setup, verification, and management. Updates user and settings models, email helper, and relevant controllers to support 2FA policy enforcement, configuration, and user flows. Enhances security by allowing admins to require or disable 2FA, and provides backup code generation and management for account recovery.
2025-10-16 17:25:06 +03:00
|
|
|
|
|
|
|
|
public function updateTwoFactor()
|
|
|
|
|
{
|
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
|
|
|
$this->redirect('/settings');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CSRF Protection
|
|
|
|
|
$this->verifyCsrf('/settings#security');
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$twoFactorPolicy = trim($_POST['two_factor_policy'] ?? 'optional');
|
|
|
|
|
$rateLimitMinutes = (int)($_POST['two_factor_rate_limit_minutes'] ?? 15);
|
|
|
|
|
$emailCodeExpiryMinutes = (int)($_POST['two_factor_email_code_expiry_minutes'] ?? 10);
|
|
|
|
|
|
|
|
|
|
// Validate policy
|
|
|
|
|
$validPolicies = ['disabled', 'optional', 'forced'];
|
|
|
|
|
if (!in_array($twoFactorPolicy, $validPolicies)) {
|
|
|
|
|
$_SESSION['error'] = 'Invalid 2FA policy selected';
|
|
|
|
|
$this->redirect('/settings#security');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate rate limit (1-60 minutes)
|
|
|
|
|
if ($rateLimitMinutes < 1 || $rateLimitMinutes > 60) {
|
|
|
|
|
$_SESSION['error'] = 'Rate limit must be between 1 and 60 minutes';
|
|
|
|
|
$this->redirect('/settings#security');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate email code expiry (1-30 minutes)
|
|
|
|
|
if ($emailCodeExpiryMinutes < 1 || $emailCodeExpiryMinutes > 30) {
|
|
|
|
|
$_SESSION['error'] = 'Email code expiry must be between 1 and 30 minutes';
|
|
|
|
|
$this->redirect('/settings#security');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$twoFactorSettings = [
|
|
|
|
|
'two_factor_policy' => $twoFactorPolicy,
|
|
|
|
|
'two_factor_rate_limit_minutes' => $rateLimitMinutes,
|
|
|
|
|
'two_factor_email_code_expiry_minutes' => $emailCodeExpiryMinutes
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$this->settingModel->updateTwoFactorSettings($twoFactorSettings);
|
|
|
|
|
|
|
|
|
|
$_SESSION['success'] = 'Two-Factor Authentication settings updated successfully';
|
|
|
|
|
$this->redirect('/settings#security');
|
|
|
|
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
$_SESSION['error'] = 'Failed to update 2FA settings: ' . $e->getMessage();
|
|
|
|
|
$this->redirect('/settings#security');
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-10-08 18:54:34 +03:00
|
|
|
}
|
|
|
|
|
|