2025-10-08 18:54:34 +03:00
< ? php
$title = 'Settings' ;
$pageTitle = 'System Settings' ;
$pageDescription = 'Configure application, email, and monitoring settings' ;
$pageIcon = 'fas fa-cog' ;
ob_start ();
$currentNotificationDays = $settings [ 'notification_days_before' ] ? ? '30,15,7,3,1' ;
$currentCheckInterval = $settings [ 'check_interval_hours' ] ? ? '24' ;
$lastCheckRun = $settings [ 'last_check_run' ] ? ? null ;
// Get timezone list (popular ones first)
$popularTimezones = [
'UTC' => 'UTC' ,
'America/New_York' => 'Eastern Time (US)' ,
'America/Chicago' => 'Central Time (US)' ,
'America/Denver' => 'Mountain Time (US)' ,
'America/Los_Angeles' => 'Pacific Time (US)' ,
'Europe/London' => 'London' ,
'Europe/Paris' => 'Paris' ,
'Asia/Tokyo' => 'Tokyo' ,
'Australia/Sydney' => 'Sydney'
];
// Determine which preset is selected
$selectedPreset = 'custom' ;
foreach ( $notificationPresets as $key => $preset ) {
if ( $preset [ 'value' ] === $currentNotificationDays ) {
$selectedPreset = $key ;
break ;
}
}
?>
<!-- Tabs Navigation -->
< div class = " bg-white rounded-lg border border-gray-200 mb-6 " >
< div class = " border-b border-gray-200 " >
< nav class = " flex -mb-px overflow-x-auto " >
< button onclick = " switchTab('app') " id = " tab-app " class = " tab-button px-6 py-3 text-sm font-medium border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap " >
< i class = " fas fa-cog mr-2 " ></ i >
Application
</ button >
< button onclick = " switchTab('email') " id = " tab-email " class = " tab-button px-6 py-3 text-sm font-medium border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap " >
< i class = " fas fa-envelope mr-2 " ></ i >
Email
</ button >
< button onclick = " switchTab('monitoring') " id = " tab-monitoring " class = " tab-button px-6 py-3 text-sm font-medium border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap " >
< i class = " fas fa-bell mr-2 " ></ i >
Monitoring
</ button >
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
< button onclick = " switchTab('security') " id = " tab-security " class = " tab-button px-6 py-3 text-sm font-medium border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap " >
< i class = " fas fa-shield-alt mr-2 " ></ i >
Security
</ button >
2025-10-08 18:54:34 +03:00
< button onclick = " switchTab('system') " id = " tab-system " class = " tab-button px-6 py-3 text-sm font-medium border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap " >
< i class = " fas fa-server mr-2 " ></ i >
System
</ button >
< button onclick = " switchTab('maintenance') " id = " tab-maintenance " class = " tab-button px-6 py-3 text-sm font-medium border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap " >
< i class = " fas fa-tools mr-2 " ></ i >
Maintenance
</ button >
</ nav >
</ div >
</ div >
<!-- Tab Content : Application Settings -->
< div id = " content-app " class = " tab-content " >
< div class = " bg-white rounded-lg border border-gray-200 overflow-hidden " >
< div class = " px-6 py-4 border-b border-gray-200 bg-gray-50 " >
< h3 class = " text-lg font-semibold text-gray-900 " > Application Settings </ h3 >
< p class = " text-sm text-gray-600 mt-1 " > Configure basic application information </ p >
</ div >
< form method = " POST " action = " /settings/update-app " class = " p-6 " >
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_field () ?>
2025-10-08 18:54:34 +03:00
< div class = " space-y-4 " >
< div >
< label for = " app_name " class = " block text-sm font-medium text-gray-700 mb-2 " >
Application Name
</ label >
< input type = " text " id = " app_name " name = " app_name " required
value = " <?= htmlspecialchars( $appSettings['app_name'] ) ?> "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
< p class = " text-xs text-gray-500 mt-1 " > Name displayed in the interface </ p >
</ div >
< div >
< label for = " app_url " class = " block text-sm font-medium text-gray-700 mb-2 " >
Application URL
</ label >
< input type = " url " id = " app_url " name = " app_url " required
value = " <?= htmlspecialchars( $appSettings['app_url'] ) ?> "
placeholder = " https://domains.example.com "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
< p class = " text-xs text-gray-500 mt-1 " > Base URL for the application ( used in emails and links ) </ p >
</ div >
< div >
< label for = " app_timezone " class = " block text-sm font-medium text-gray-700 mb-2 " >
Timezone
</ label >
< select id = " app_timezone " name = " app_timezone " required
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
< ? php foreach ( $popularTimezones as $tz => $label ) : ?>
< option value = " <?= htmlspecialchars( $tz ) ?> " < ? = $appSettings [ 'app_timezone' ] === $tz ? 'selected' : '' ?> >
< ? = htmlspecialchars ( $label ) ?>
</ option >
< ? php endforeach ; ?>
< option disabled > ────────── </ option >
< ? php
$allTimezones = timezone_identifiers_list ();
foreach ( $allTimezones as $tz ) :
if ( ! isset ( $popularTimezones [ $tz ])) :
?>
< option value = " <?= htmlspecialchars( $tz ) ?> " < ? = $appSettings [ 'app_timezone' ] === $tz ? 'selected' : '' ?> >
< ? = htmlspecialchars ( $tz ) ?>
</ option >
< ? php
endif ;
endforeach ;
?>
</ select >
< p class = " text-xs text-gray-500 mt-1 " > Application timezone for dates and times </ p >
</ div >
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
<!-- User Registration Settings -->
< div class = " border-t border-gray-200 pt-4 mt-6 " >
< h4 class = " text-base font-semibold text-gray-900 mb-4 " > User Registration </ h4 >
< div class = " space-y-3 " >
< div class = " flex items-start " >
< div class = " flex items-center h-5 " >
< input type = " checkbox " id = " registration_enabled " name = " registration_enabled " value = " 1 "
< ? = ! empty ( $settings [ 'registration_enabled' ]) ? 'checked' : '' ?>
class = " w-4 h-4 text-primary border-gray-300 rounded focus:ring-primary " >
</ div >
< div class = " ml-3 " >
< label for = " registration_enabled " class = " text-sm font-medium text-gray-700 " >
Enable User Registration
</ label >
< p class = " text-xs text-gray-500 mt-1 " > Allow new users to create accounts via registration form </ p >
</ div >
</ div >
< div class = " flex items-start " >
< div class = " flex items-center h-5 " >
< input type = " checkbox " id = " require_email_verification " name = " require_email_verification " value = " 1 "
< ? = ! empty ( $settings [ 'require_email_verification' ]) ? 'checked' : '' ?>
class = " w-4 h-4 text-primary border-gray-300 rounded focus:ring-primary " >
</ div >
< div class = " ml-3 " >
< label for = " require_email_verification " class = " text-sm font-medium text-gray-700 " >
Require Email Verification
</ label >
< p class = " text-xs text-gray-500 mt-1 " > Users must verify their email address before accessing the system </ p >
</ div >
</ div >
</ div >
</ div >
2025-10-08 18:54:34 +03:00
</ div >
< div class = " flex items-center justify-between pt-6 mt-6 border-t border-gray-200 " >
< button type = " submit " class = " inline-flex items-center px-4 py-2.5 bg-primary text-white text-sm rounded-lg hover:bg-primary-dark transition-colors font-medium " >
< i class = " fas fa-save mr-2 " ></ i >
Save Application Settings
</ button >
</ div >
</ form >
</ div >
</ div >
<!-- Tab Content : Email Settings -->
< div id = " content-email " class = " tab-content hidden " >
< div class = " bg-white rounded-lg border border-gray-200 overflow-hidden " >
< div class = " px-6 py-4 border-b border-gray-200 bg-gray-50 " >
< h3 class = " text-lg font-semibold text-gray-900 " > Email Settings </ h3 >
< p class = " text-sm text-gray-600 mt-1 " > Configure SMTP server for sending notifications </ p >
</ div >
< form method = " POST " action = " /settings/update-email " class = " p-6 " >
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_field () ?>
2025-10-08 18:54:34 +03:00
< div class = " grid grid-cols-1 md:grid-cols-2 gap-4 " >
< div >
< label for = " mail_host " class = " block text-sm font-medium text-gray-700 mb-2 " >
SMTP Host < span class = " text-red-500 " >*</ span >
</ label >
< input type = " text " id = " mail_host " name = " mail_host " required
value = " <?= htmlspecialchars( $emailSettings['mail_host'] ) ?> "
placeholder = " smtp.mailtrap.io "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
</ div >
< div >
< label for = " mail_port " class = " block text-sm font-medium text-gray-700 mb-2 " >
SMTP Port < span class = " text-red-500 " >*</ span >
</ label >
< input type = " number " id = " mail_port " name = " mail_port " required
value = " <?= htmlspecialchars( $emailSettings['mail_port'] ) ?> "
placeholder = " 2525 "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
</ div >
< div >
< label for = " mail_encryption " class = " block text-sm font-medium text-gray-700 mb-2 " >
2025-10-14 00:27:50 +03:00
Encryption < span class = " text-blue-500 text-xs " > ( Auto - detected by port ) </ span >
2025-10-08 18:54:34 +03:00
</ label >
< select id = " mail_encryption " name = " mail_encryption "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
2025-10-14 00:27:50 +03:00
< option value = " tls " < ? = $emailSettings [ 'mail_encryption' ] === 'tls' ? 'selected' : '' ?> >TLS (STARTTLS)</option>
< option value = " ssl " < ? = $emailSettings [ 'mail_encryption' ] === 'ssl' ? 'selected' : '' ?> >SSL (SMTPS)</option>
2025-10-08 18:54:34 +03:00
< option value = " " < ? = empty ( $emailSettings [ 'mail_encryption' ]) ? 'selected' : '' ?> >None</option>
</ select >
2025-10-14 00:27:50 +03:00
< p class = " text-xs text-gray-500 mt-1 " >
< i class = " fas fa-magic text-blue-600 mr-1 " ></ i >
< span id = " encryption-help " > Will auto - update based on port selection </ span >
</ p >
2025-10-08 18:54:34 +03:00
</ div >
2025-10-14 00:31:47 +03:00
< div class = " md:col-span-2 " >
< div class = " bg-gray-50 border border-gray-200 rounded-lg p-3 " >
< p class = " text-xs text-gray-600 " >
< i class = " fas fa-info-circle text-gray-400 mr-1 " ></ i >
< strong > Protocol :</ strong > This application uses SMTP ( Simple Mail Transfer Protocol ) for sending emails .
</ p >
</ div >
</ div >
2025-10-08 18:54:34 +03:00
< div >
< label for = " mail_username " class = " block text-sm font-medium text-gray-700 mb-2 " >
SMTP Username
</ label >
< input type = " text " id = " mail_username " name = " mail_username "
value = " <?= htmlspecialchars( $emailSettings['mail_username'] ) ?> "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
</ div >
< div >
< label for = " mail_password " class = " block text-sm font-medium text-gray-700 mb-2 " >
SMTP Password
</ label >
< input type = " password " id = " mail_password " name = " mail_password "
value = " <?= htmlspecialchars( $emailSettings['mail_password'] ) ?> "
placeholder = " •••••••• "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
< p class = " text-xs text-gray-500 mt-1 " >
< i class = " fas fa-lock text-green-600 mr-1 " ></ i >
Encrypted before storing in database
</ p >
</ div >
< div >
< label for = " mail_from_address " class = " block text-sm font-medium text-gray-700 mb-2 " >
From Email < span class = " text-red-500 " >*</ span >
</ label >
< input type = " email " id = " mail_from_address " name = " mail_from_address " required
value = " <?= htmlspecialchars( $emailSettings['mail_from_address'] ) ?> "
placeholder = " noreply@domainmonitor.com "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
</ div >
< div >
< label for = " mail_from_name " class = " block text-sm font-medium text-gray-700 mb-2 " >
From Name
</ label >
< input type = " text " id = " mail_from_name " name = " mail_from_name "
value = " <?= htmlspecialchars( $emailSettings['mail_from_name'] ) ?> "
placeholder = " Domain Monitor "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
</ div >
</ div >
< div class = " flex items-center justify-between pt-6 mt-6 border-t border-gray-200 " >
< button type = " submit " class = " inline-flex items-center px-4 py-2.5 bg-primary text-white text-sm rounded-lg hover:bg-primary-dark transition-colors font-medium " >
< i class = " fas fa-save mr-2 " ></ i >
Save Email Settings
</ button >
</ div >
</ form >
<!-- Test Email Section -->
< div class = " px-6 pb-6 " >
< div class = " bg-blue-50 border border-blue-200 rounded-lg p-4 " >
< div class = " flex items-start justify-between " >
< div class = " flex-1 " >
< h4 class = " text-sm font-semibold text-gray-900 mb-1 " > Test Email Configuration </ h4 >
< p class = " text-sm text-gray-700 mb-3 " >
Send a test email to verify your SMTP settings are configured correctly .
</ p >
< form method = " POST " action = " /settings/test-email " id = " testEmailForm " class = " flex gap-2 " >
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_field () ?>
2025-10-08 18:54:34 +03:00
< input type = " email " name = " test_email " id = " test_email " required
placeholder = " Enter email address to receive test "
class = " flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary text-sm " >
< button type = " submit " class = " inline-flex items-center px-4 py-2 bg-blue-600 text-white text-sm rounded-lg hover:bg-blue-700 transition-colors font-medium " >
< i class = " fas fa-paper-plane mr-2 " ></ i >
Send Test Email
</ button >
</ form >
</ div >
</ div >
</ div >
</ div >
</ div >
</ div >
<!-- Tab Content : Monitoring Settings -->
< div id = " content-monitoring " class = " tab-content hidden " >
< div class = " bg-white rounded-lg border border-gray-200 overflow-hidden " >
< div class = " px-6 py-4 border-b border-gray-200 bg-gray-50 " >
< h3 class = " text-lg font-semibold text-gray-900 " > Monitoring Settings </ h3 >
< p class = " text-sm text-gray-600 mt-1 " > Configure notification schedules and check intervals </ p >
</ div >
< form method = " POST " action = " /settings/update " id = " settingsForm " class = " p-6 " >
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_field () ?>
2025-10-08 18:54:34 +03:00
<!-- Notification Settings -->
< div class = " mb-6 " >
< h4 class = " text-base font-semibold text-gray-900 mb-4 flex items-center " >
< i class = " fas fa-bell text-primary mr-2 " ></ i >
Notification Schedule
</ h4 >
< div class = " space-y-4 " >
< div >
< label for = " notification_preset " class = " block text-sm font-medium text-gray-700 mb-2 " >
Choose Preset
</ label >
< select class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary "
id = " notification_preset " name = " notification_preset " >
< ? php foreach ( $notificationPresets as $key => $preset ) : ?>
< option value = " <?= htmlspecialchars( $key ) ?> "
data - value = " <?= htmlspecialchars( $preset['value'] ) ?> "
< ? = $selectedPreset === $key ? 'selected' : '' ?> >
< ? = htmlspecialchars ( $preset [ 'label' ]) ?>
</ option >
< ? php endforeach ; ?>
</ select >
</ div >
< input type = " hidden " id = " notification_days_before " name = " notification_days_before "
value = " <?= htmlspecialchars( $currentNotificationDays ) ?> " >
<!-- Custom days input -->
< div id = " custom_days_container " style = " display: <?= $selectedPreset === 'custom' ? 'block' : 'none' ?>; " >
< label for = " custom_notification_days " class = " block text-sm font-medium text-gray-700 mb-2 " >
Custom Days
</ label >
< input type = " text "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary "
id = " custom_notification_days "
name = " custom_notification_days "
value = " <?= $selectedPreset === 'custom' ? htmlspecialchars( $currentNotificationDays ) : '' ?> "
placeholder = " e.g., 90,60,30,14,7,3,1 " >
< p class = " text-xs text-gray-500 mt-1 " > Comma - separated numbers ( will be sorted automatically ) </ p >
</ div >
<!-- Preview -->
< div class = " bg-blue-50 border border-blue-200 rounded-lg p-3 " >
< p class = " text-sm text-gray-700 " >
< i class = " fas fa-info-circle text-blue-500 mr-1 " ></ i >
Alerts at : < span id = " days_preview " class = " font-semibold text-primary " >< ? = htmlspecialchars ( $currentNotificationDays ) ?> </span> days
</ p >
</ div >
</ div >
</ div >
< div class = " border-t border-gray-200 my-6 " ></ div >
<!-- Check Interval -->
< div class = " mb-6 " >
< h4 class = " text-base font-semibold text-gray-900 mb-4 flex items-center " >
< i class = " fas fa-clock text-primary mr-2 " ></ i >
Domain Check Interval
</ h4 >
< div class = " grid grid-cols-1 md:grid-cols-2 gap-4 " >
< div >
< label for = " check_interval_hours " class = " block text-sm font-medium text-gray-700 mb-2 " >
Check Every
</ label >
< select class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary "
id = " check_interval_hours " name = " check_interval_hours " >
< ? php foreach ( $checkIntervalPresets as $preset ) : ?>
< option value = " <?= $preset['value'] ?> "
< ? = $currentCheckInterval == $preset [ 'value' ] ? 'selected' : '' ?> >
< ? = htmlspecialchars ( $preset [ 'label' ]) ?>
</ option >
< ? php endforeach ; ?>
</ select >
</ div >
< div >
< label class = " block text-sm font-medium text-gray-700 mb-2 " >
Last Check Run
</ label >
< div class = " px-3 py-2 bg-gray-50 border border-gray-200 rounded-lg " >
< ? php if ( $lastCheckRun ) : ?>
< div class = " flex items-center text-sm " >
< i class = " fas fa-check-circle text-green-500 mr-2 " ></ i >
< span class = " text-gray-700 " >< ? = date ( 'M d, Y H:i' , strtotime ( $lastCheckRun )) ?> </span>
</ div >
< ? php else : ?>
< div class = " flex items-center text-sm " >
< i class = " fas fa-minus-circle text-gray-400 mr-2 " ></ i >
< span class = " text-gray-500 " > Never run </ span >
</ div >
< ? php endif ; ?>
</ div >
</ div >
</ div >
</ div >
<!-- Actions -->
< div class = " flex items-center justify-between pt-4 border-t border-gray-200 " >
< button type = " submit " class = " inline-flex items-center px-4 py-2.5 bg-primary text-white text-sm rounded-lg hover:bg-primary-dark transition-colors font-medium " >
< i class = " fas fa-save mr-2 " ></ i >
Save Monitoring Settings
</ button >
</ div >
</ form >
</ div >
</ div >
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
<!-- Tab Content : Security Settings -->
< div id = " content-security " class = " tab-content hidden " >
< div class = " bg-white rounded-lg border border-gray-200 overflow-hidden " >
< div class = " px-6 py-4 border-b border-gray-200 bg-gray-50 " >
< h3 class = " text-lg font-semibold text-gray-900 " > Security Settings </ h3 >
< p class = " text-sm text-gray-600 mt-1 " > Configure CAPTCHA protection for authentication forms </ p >
</ div >
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
<!-- CAPTCHA Settings -->
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
< form method = " POST " action = " /settings/update-captcha " class = " p-6 " >
< ? = csrf_field () ?>
< div class = " space-y-4 " >
<!-- CAPTCHA Provider Selection -->
< div >
< label for = " captcha_provider " class = " block text-sm font-medium text-gray-700 mb-2 " >
CAPTCHA Provider
</ label >
< select id = " captcha_provider " name = " captcha_provider "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
< option value = " disabled " < ? = ( $captchaSettings [ 'provider' ] ? ? 'disabled' ) === 'disabled' ? 'selected' : '' ?> >
Disabled ( No CAPTCHA )
</ option >
< option value = " recaptcha_v2 " < ? = ( $captchaSettings [ 'provider' ] ? ? '' ) === 'recaptcha_v2' ? 'selected' : '' ?> >
Google reCAPTCHA v2 ( Checkbox )
</ option >
< option value = " recaptcha_v3 " < ? = ( $captchaSettings [ 'provider' ] ? ? '' ) === 'recaptcha_v3' ? 'selected' : '' ?> >
Google reCAPTCHA v3 ( Invisible )
</ option >
< option value = " turnstile " < ? = ( $captchaSettings [ 'provider' ] ? ? '' ) === 'turnstile' ? 'selected' : '' ?> >
Cloudflare Turnstile
</ option >
</ select >
< p class = " text-xs text-gray-500 mt-1 " > CAPTCHA protects login , registration , and password reset forms </ p >
</ div >
<!-- CAPTCHA Configuration Fields ( shown when enabled ) -->
< div id = " captcha_config " style = " display: <?= ( $captchaSettings['provider'] ?? 'disabled') !== 'disabled' ? 'block' : 'none' ?>; " >
< div class = " border-t border-gray-200 pt-4 mt-4 " >
<!-- Site Key -->
< div class = " mb-4 " >
< label for = " captcha_site_key " class = " block text-sm font-medium text-gray-700 mb-2 " >
Site Key ( Public Key )
</ label >
< input type = " text " id = " captcha_site_key " name = " captcha_site_key "
value = " <?= htmlspecialchars( $captchaSettings['site_key'] ?? '') ?> "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary "
placeholder = " Enter your site/public key " >
< p class = " text-xs text-gray-500 mt-1 " > Public key visible in HTML source </ p >
</ div >
<!-- Secret Key -->
< div class = " mb-4 " >
< label for = " captcha_secret_key " class = " block text-sm font-medium text-gray-700 mb-2 " >
Secret Key
</ label >
< input type = " password " id = " captcha_secret_key " name = " captcha_secret_key "
value = " "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary "
placeholder = " <?= !empty( $captchaSettings['secret_key'] ) ? '••••••••••••••••' : 'Enter your secret key' ?> " >
< p class = " text-xs text-gray-500 mt-1 " >
< i class = " fas fa-lock text-green-600 mr-1 " ></ i >
Encrypted before storing in database . Leave blank to keep existing key .
</ p >
</ div >
<!-- reCAPTCHA v3 Score Threshold ( only for v3 ) -->
< div id = " recaptcha_v3_threshold " style = " display: <?= ( $captchaSettings['provider'] ?? '') === 'recaptcha_v3' ? 'block' : 'none' ?>; " >
< label for = " recaptcha_v3_score_threshold " class = " block text-sm font-medium text-gray-700 mb-2 " >
reCAPTCHA v3 Score Threshold
</ label >
< input type = " number " id = " recaptcha_v3_score_threshold " name = " recaptcha_v3_score_threshold "
value = " <?= htmlspecialchars( $captchaSettings['score_threshold'] ?? '0.5') ?> "
min = " 0.0 " max = " 1.0 " step = " 0.1 "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
< p class = " text-xs text-gray-500 mt-1 " > Minimum score required ( 0.0 to 1.0 ) . Default : 0.5 . Lower = more permissive .</ p >
</ div >
</ div >
<!-- Provider - specific Documentation -->
< div id = " captcha_docs " class = " bg-blue-50 border border-blue-200 rounded-lg p-4 mt-4 " >
< p class = " text-sm font-medium text-gray-900 mb-2 " >
< i class = " fas fa-info-circle text-blue-500 mr-1 " ></ i >
< span id = " captcha_docs_title " > Setup Instructions </ span >
</ p >
< div id = " docs_recaptcha_v2 " class = " text-sm text-gray-700 " style = " display: none; " >
< p class = " mb-1 " > 1. Visit < a href = " https://www.google.com/recaptcha/admin " target = " _blank " class = " text-primary hover:underline " > Google reCAPTCHA Admin Console </ a ></ p >
< p class = " mb-1 " > 2. Register a new site with reCAPTCHA v2 " I'm not a robot " Checkbox </ p >
< p > 3. Copy the Site Key and Secret Key to the fields above </ p >
</ div >
< div id = " docs_recaptcha_v3 " class = " text-sm text-gray-700 " style = " display: none; " >
< p class = " mb-1 " > 1. Visit < a href = " https://www.google.com/recaptcha/admin " target = " _blank " class = " text-primary hover:underline " > Google reCAPTCHA Admin Console </ a ></ p >
< p class = " mb-1 " > 2. Register a new site with reCAPTCHA v3 </ p >
< p class = " mb-1 " > 3. Copy the Site Key and Secret Key to the fields above </ p >
< p > 4. Adjust the score threshold based on your security needs ( 0.5 is recommended ) </ p >
</ div >
< div id = " docs_turnstile " class = " text-sm text-gray-700 " style = " display: none; " >
< p class = " mb-1 " > 1. Visit < a href = " https://dash.cloudflare.com/?to=/:account/turnstile " target = " _blank " class = " text-primary hover:underline " > Cloudflare Turnstile Dashboard </ a ></ p >
< p class = " mb-1 " > 2. Create a new Turnstile widget </ p >
< p class = " mb-1 " > 3. Choose " Managed " mode for best user experience </ p >
< p > 4. Copy the Site Key and Secret Key to the fields above </ p >
</ div >
</ div >
</ div >
</ div >
< div class = " flex items-center justify-between pt-6 mt-6 border-t border-gray-200 " >
< button type = " submit " class = " inline-flex items-center px-4 py-2.5 bg-primary text-white text-sm rounded-lg hover:bg-primary-dark transition-colors font-medium " >
< i class = " fas fa-save mr-2 " ></ i >
Save Security Settings
</ button >
</ div >
</ form >
</ div >
2025-10-17 11:13:25 +03:00
<!-- Two - Factor Authentication Settings -->
< div class = " bg-white rounded-lg border border-gray-200 overflow-hidden mt-6 " >
< div class = " px-6 py-4 border-b border-gray-200 bg-gray-50 " >
< h3 class = " text-lg font-semibold text-gray-900 " > Two - Factor Authentication </ h3 >
< p class = " text-sm text-gray-600 mt-1 " > Configure 2 FA policy and security settings </ p >
</ div >
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
2025-10-17 11:13:25 +03:00
< form method = " POST " action = " /settings/update-two-factor " class = " p-6 " >
< ? = csrf_field () ?>
< div class = " space-y-4 " >
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
< div >
2025-10-17 11:13:25 +03:00
< label for = " two_factor_policy " class = " block text-sm font-medium text-gray-700 mb-2 " >
2 FA Policy
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
</ label >
2025-10-17 11:13:25 +03:00
< select id = " two_factor_policy " name = " two_factor_policy "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
< option value = " disabled " < ? = ( $twoFactorSettings [ 'policy' ] ? ? 'optional' ) === 'disabled' ? 'selected' : '' ?> >
Disabled - No 2 FA features available
</ option >
< option value = " optional " < ? = ( $twoFactorSettings [ 'policy' ] ? ? 'optional' ) === 'optional' ? 'selected' : '' ?> >
Optional - Users can choose to enable 2 FA
</ option >
< option value = " forced " < ? = ( $twoFactorSettings [ 'policy' ] ? ? 'optional' ) === 'forced' ? 'selected' : '' ?> >
Forced - All users must enable 2 FA ( email verification required )
</ option >
</ select >
< p class = " text-xs text-gray-500 mt-1 " >
< i class = " fas fa-info-circle text-blue-500 mr-1 " ></ i >
Users must have verified email addresses to enable 2 FA
</ p >
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
</ div >
2025-10-17 11:13:25 +03:00
< div class = " grid grid-cols-1 md:grid-cols-2 gap-4 " >
< div >
< label for = " two_factor_rate_limit_minutes " class = " block text-sm font-medium text-gray-700 mb-2 " >
Rate Limit ( minutes )
</ label >
< input type = " number " id = " two_factor_rate_limit_minutes " name = " two_factor_rate_limit_minutes "
value = " <?= htmlspecialchars( $twoFactorSettings['rate_limit_minutes'] ?? 15) ?> "
min = " 1 " max = " 60 "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
< p class = " text-xs text-gray-500 mt-1 " > Maximum failed attempts per IP address </ p >
</ div >
< div >
< label for = " two_factor_email_code_expiry_minutes " class = " block text-sm font-medium text-gray-700 mb-2 " >
Email Code Expiry ( minutes )
</ label >
< input type = " number " id = " two_factor_email_code_expiry_minutes " name = " two_factor_email_code_expiry_minutes "
value = " <?= htmlspecialchars( $twoFactorSettings['email_code_expiry_minutes'] ?? 10) ?> "
min = " 1 " max = " 30 "
class = " w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary " >
< p class = " text-xs text-gray-500 mt-1 " > How long email backup codes remain valid </ p >
</ div >
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
</ div >
2025-10-17 11:13:25 +03:00
<!-- 2 FA Info Box -->
< div class = " bg-blue-50 border border-blue-200 rounded-lg p-4 " >
< p class = " text-sm font-medium text-gray-900 mb-2 " >
< i class = " fas fa-info-circle text-blue-500 mr-1 " ></ i >
Two - Factor Authentication Features
</ p >
< ul class = " text-sm text-gray-700 space-y-1 " >
< li > • < strong > TOTP Authenticator Apps :</ strong > Google Authenticator , Authy , Microsoft Authenticator </ li >
< li > • < strong > Email Backup Codes :</ strong > One - time codes sent to verified email addresses </ li >
< li > • < strong > Backup Recovery Codes :</ strong > 8 single - use codes generated during setup </ li >
< li > • < strong > Rate Limiting :</ strong > Prevents brute force attacks on verification codes </ li >
</ ul >
</ div >
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
</ div >
2025-10-17 11:13:25 +03:00
< div class = " flex items-center justify-between pt-6 mt-6 border-t border-gray-200 " >
< button type = " submit " class = " inline-flex items-center px-4 py-2.5 bg-green-600 text-white text-sm rounded-lg hover:bg-green-700 transition-colors font-medium " >
< i class = " fas fa-shield-alt mr-2 " ></ i >
Save 2 FA Settings
</ button >
</ div >
</ form >
</ div >
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
</ div >
2025-10-08 18:54:34 +03:00
<!-- Tab Content : System Information -->
< div id = " content-system " class = " tab-content hidden " >
< div class = " bg-white rounded-lg border border-gray-200 overflow-hidden " >
< div class = " px-6 py-4 border-b border-gray-200 bg-gray-50 " >
< h3 class = " text-lg font-semibold text-gray-900 " > System Information </ h3 >
< p class = " text-sm text-gray-600 mt-1 " > Cron job configuration and log file locations </ p >
</ div >
< div class = " p-6 space-y-6 " >
<!-- Cron Command -->
< div >
< h4 class = " text-sm font-semibold text-gray-900 mb-2 flex items-center " >
< i class = " fas fa-terminal text-blue-500 mr-2 " ></ i >
Cron Job Command
</ h4 >
< div class = " bg-gray-900 text-gray-100 px-4 py-3 rounded-lg font-mono text-sm " >
< code > php cron / check_domains . php </ code >
</ div >
</ div >
<!-- Crontab Entry -->
< div >
< h4 class = " text-sm font-semibold text-gray-900 mb-2 flex items-center " >
< i class = " fas fa-calendar-alt text-green-500 mr-2 " ></ i >
Recommended Crontab Entry
</ h4 >
< div class = " bg-gray-900 text-gray-100 px-4 py-3 rounded-lg font-mono text-sm break-all " >
2025-10-09 17:08:10 +05:30
< code > 0 */< ? = $currentCheckInterval ?> * * * php <?= realpath(PATH_ROOT . 'cron/check_domains.php') ?></code>
2025-10-08 18:54:34 +03:00
</ div >
< p class = " text-xs text-gray-500 mt-2 " > Update the path to match your server installation </ p >
</ div >
<!-- Log Files -->
< div >
< h4 class = " text-sm font-semibold text-gray-900 mb-3 flex items-center " >
< i class = " fas fa-file-alt text-orange-500 mr-2 " ></ i >
Log Files
</ h4 >
< div class = " space-y-2 " >
< div class = " flex items-center justify-between p-3 bg-gray-50 rounded-lg border border-gray-200 " >
< div >
< p class = " text-sm font-medium text-gray-900 " > Cron Log </ p >
< p class = " text-xs text-gray-500 mt-0.5 " > Domain check execution logs </ p >
</ div >
< code class = " text-xs bg-gray-900 text-gray-100 px-2 py-1 rounded " > logs / cron . log </ code >
</ div >
< div class = " flex items-center justify-between p-3 bg-gray-50 rounded-lg border border-gray-200 " >
< div >
< p class = " text-sm font-medium text-gray-900 " > TLD Import Log </ p >
< p class = " text-xs text-gray-500 mt-0.5 " > TLD registry import logs </ p >
</ div >
< code class = " text-xs bg-gray-900 text-gray-100 px-2 py-1 rounded " > logs / tld_import_ *. log </ code >
</ div >
</ div >
</ div >
</ div >
</ div >
</ div >
<!-- Tab Content : Maintenance -->
< div id = " content-maintenance " class = " tab-content hidden " >
< div class = " bg-white rounded-lg border border-gray-200 overflow-hidden " >
< div class = " px-6 py-4 border-b border-gray-200 bg-gray-50 " >
< h3 class = " text-lg font-semibold text-gray-900 " > Maintenance Tools </ h3 >
< p class = " text-sm text-gray-600 mt-1 " > Database cleanup and system maintenance </ p >
</ div >
< div class = " p-6 " >
<!-- Clear Logs -->
< div class = " mb-6 " >
< h4 class = " text-base font-semibold text-gray-900 mb-3 flex items-center " >
< i class = " fas fa-trash-alt text-red-500 mr-2 " ></ i >
Clear Old Notification Logs
</ h4 >
< div class = " bg-yellow-50 border border-yellow-200 rounded-lg p-4 mb-4 " >
< div class = " flex " >
< i class = " fas fa-exclamation-triangle text-yellow-600 mt-0.5 mr-3 " ></ i >
< div >
< p class = " text-sm font-medium text-gray-900 " > Warning </ p >
< p class = " text-sm text-gray-700 mt-1 " >
This will permanently delete all notification logs older than 30 days . This action cannot be undone .
</ p >
</ div >
</ div >
</ div >
< form method = " POST " action = " /settings/clear-logs " onsubmit = " return confirm('Are you sure you want to clear logs older than 30 days? This action cannot be undone.') " >
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_field () ?>
2025-10-08 18:54:34 +03:00
< button type = " submit " class = " inline-flex items-center px-4 py-2.5 bg-red-600 text-white text-sm rounded-lg hover:bg-red-700 transition-colors font-medium " >
< i class = " fas fa-trash-alt mr-2 " ></ i >
Clear Old Logs
</ button >
</ form >
</ div >
<!-- Future maintenance tools can be added here -->
< div class = " border-t border-gray-200 pt-6 mt-6 " >
< div class = " bg-blue-50 border border-blue-200 rounded-lg p-4 " >
< div class = " flex " >
< i class = " fas fa-lightbulb text-blue-500 mt-0.5 mr-3 " ></ i >
< div >
< p class = " text-sm font-medium text-gray-900 " > Database Optimization </ p >
< p class = " text-sm text-gray-700 mt-1 " >
Regular maintenance keeps your system running smoothly . Consider clearing old logs monthly .
</ p >
</ div >
</ div >
</ div >
</ div >
</ div >
</ div >
</ div >
< script >
2025-10-14 00:27:50 +03:00
// Auto-update encryption based on port
function updateEncryptionByPort () {
const portField = document . getElementById ( 'mail_port' );
const encryptionField = document . getElementById ( 'mail_encryption' );
const helpText = document . getElementById ( 'encryption-help' );
if ( ! portField || ! encryptionField ) return ;
const port = parseInt ( portField . value );
// Auto-select encryption based on port
if ( port === 465 ) {
encryptionField . value = 'ssl' ;
helpText . innerHTML = '<i class="fas fa-check text-green-600 mr-1"></i>Port 465 detected: SSL encryption selected' ;
helpText . className = 'text-xs text-green-600 mt-1' ;
} else if ( port === 587 ) {
encryptionField . value = 'tls' ;
helpText . innerHTML = '<i class="fas fa-check text-green-600 mr-1"></i>Port 587 detected: TLS encryption selected' ;
helpText . className = 'text-xs text-green-600 mt-1' ;
} else if ( port === 25 || port === 2525 ) {
// Keep current selection but show info
helpText . innerHTML = '<i class="fas fa-info text-blue-600 mr-1"></i>Port ' + port + ': Choose TLS or None based on your server' ;
helpText . className = 'text-xs text-blue-600 mt-1' ;
} else {
helpText . innerHTML = '<i class="fas fa-question text-gray-600 mr-1"></i>Custom port: Choose encryption manually' ;
helpText . className = 'text-xs text-gray-600 mt-1' ;
}
}
// Initialize on page load
document . addEventListener ( 'DOMContentLoaded' , function () {
// Set up port change listener
const portField = document . getElementById ( 'mail_port' );
if ( portField ) {
portField . addEventListener ( 'input' , updateEncryptionByPort );
portField . addEventListener ( 'change' , updateEncryptionByPort );
// Run once on page load
updateEncryptionByPort ();
}
});
2025-10-08 18:54:34 +03:00
// Tab switching
function switchTab ( tabName ) {
// Hide all tabs
document . querySelectorAll ( '.tab-content' ) . forEach ( tab => tab . classList . add ( 'hidden' ));
document . querySelectorAll ( '.tab-button' ) . forEach ( btn => {
btn . classList . remove ( 'active' , 'border-primary' , 'text-primary' );
btn . classList . add ( 'border-transparent' , 'text-gray-500' );
});
// Show selected tab
document . getElementById ( 'content-' + tabName ) . classList . remove ( 'hidden' );
const activeBtn = document . getElementById ( 'tab-' + tabName );
activeBtn . classList . add ( 'active' , 'border-primary' , 'text-primary' );
activeBtn . classList . remove ( 'border-transparent' , 'text-gray-500' );
// Update URL hash without scrolling
history . replaceState ( null , null , '#' + tabName );
}
// Load tab from URL hash on page load
window . addEventListener ( 'DOMContentLoaded' , function () {
const hash = window . location . hash . substring ( 1 ); // Remove the #
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
const validTabs = [ 'app' , 'email' , 'monitoring' , 'security' , 'system' , 'maintenance' ];
2025-10-08 18:54:34 +03:00
if ( hash && validTabs . includes ( hash )) {
switchTab ( hash );
} else {
// Default to first tab
switchTab ( 'app' );
}
});
// Settings form logic
document . addEventListener ( 'DOMContentLoaded' , function () {
const presetSelect = document . getElementById ( 'notification_preset' );
if ( ! presetSelect ) return ;
const customContainer = document . getElementById ( 'custom_days_container' );
const customInput = document . getElementById ( 'custom_notification_days' );
const hiddenInput = document . getElementById ( 'notification_days_before' );
const daysPreview = document . getElementById ( 'days_preview' );
presetSelect . addEventListener ( 'change' , function () {
const selectedOption = this . options [ this . selectedIndex ];
const value = selectedOption . dataset . value ;
if ( this . value === 'custom' ) {
customContainer . style . display = 'block' ;
customInput . required = true ;
if ( customInput . value ) {
daysPreview . textContent = customInput . value ;
}
} else {
customContainer . style . display = 'none' ;
customInput . required = false ;
hiddenInput . value = value ;
daysPreview . textContent = value ;
}
});
customInput . addEventListener ( 'input' , function () {
if ( presetSelect . value === 'custom' ) {
daysPreview . textContent = this . value || 'Not set' ;
}
});
document . getElementById ( 'settingsForm' ) . addEventListener ( 'submit' , function ( e ) {
if ( presetSelect . value === 'custom' ) {
const customValue = customInput . value . trim ();
if ( ! customValue ) {
e . preventDefault ();
alert ( 'Please enter custom notification days' );
customInput . focus ();
return false ;
}
if ( !/^ [ \d , \s ] + $ /. test ( customValue )) {
e . preventDefault ();
alert ( 'Custom days must contain only numbers and commas' );
customInput . focus ();
return false ;
}
}
});
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
// CAPTCHA provider selection logic
const captchaProvider = document . getElementById ( 'captcha_provider' );
if ( captchaProvider ) {
const captchaConfig = document . getElementById ( 'captcha_config' );
const v3Threshold = document . getElementById ( 'recaptcha_v3_threshold' );
const docsV2 = document . getElementById ( 'docs_recaptcha_v2' );
const docsV3 = document . getElementById ( 'docs_recaptcha_v3' );
const docsTurnstile = document . getElementById ( 'docs_turnstile' );
function updateCaptchaUI () {
const selectedProvider = captchaProvider . value ;
// Show/hide configuration section
if ( selectedProvider === 'disabled' ) {
captchaConfig . style . display = 'none' ;
} else {
captchaConfig . style . display = 'block' ;
}
// Show/hide v3 threshold field
if ( selectedProvider === 'recaptcha_v3' ) {
v3Threshold . style . display = 'block' ;
} else {
v3Threshold . style . display = 'none' ;
}
// Update documentation
docsV2 . style . display = 'none' ;
docsV3 . style . display = 'none' ;
docsTurnstile . style . display = 'none' ;
if ( selectedProvider === 'recaptcha_v2' ) {
docsV2 . style . display = 'block' ;
} else if ( selectedProvider === 'recaptcha_v3' ) {
docsV3 . style . display = 'block' ;
} else if ( selectedProvider === 'turnstile' ) {
docsTurnstile . style . display = 'block' ;
}
}
captchaProvider . addEventListener ( 'change' , updateCaptchaUI );
// Initialize on page load
updateCaptchaUI ();
}
2025-10-08 18:54:34 +03:00
});
</ script >
< ? php
$content = ob_get_clean ();
include __DIR__ . '/../layout/base.php' ;
?>