Files

247 lines
12 KiB
PHP

<?php
namespace App\Http\Requests\SystemSettings;
use Illuminate\Foundation\Http\FormRequest;
class UpdateSystemConfigRequest extends FormRequest
{
public function authorize(): bool
{
$user = $this->user();
if (!$user) {
return false;
}
// Allow if Developer or legacy manage permission exists
if ($user->hasRole('Developer') || $user->can('manage global settings')) {
return true;
}
// Allow if any granular manage global settings permission exists (direct or via role)
return $user->getAllPermissions()
->contains(fn ($p) => str_starts_with($p->name, 'manage global settings:'));
}
public function rules(): array
{
return [
'app_name' => ['sometimes', 'required', 'string', 'min:3', 'max:100'],
'app_tagline' => ['nullable', 'string', 'max:150'],
'app_tagline1' => ['nullable', 'string', 'max:150'],
'app_tagline2' => ['nullable', 'string', 'max:300'],
'footer_text' => ['nullable', 'string', 'max:200'],
'default_locale' => ['nullable', 'string', 'max:10'],
'instance_mode' => ['nullable', 'string', 'in:Production,Trial,Demo'],
'app_logo' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],
'app_favicon' => ['nullable', 'image', 'mimes:png,ico,webp', 'max:1024'],
'enable_landing_page' => ['nullable', 'boolean'],
'feature_notification_center' => ['nullable', 'boolean'],
'feature_google_oauth' => ['nullable', 'boolean'],
'google_client_id' => ['nullable', 'string', 'max:255'],
'google_client_secret' => ['nullable', 'string', 'max:255'],
'feature_facebook_oauth' => ['nullable', 'boolean'],
'facebook_app_id' => ['nullable', 'string', 'max:255'],
'facebook_app_secret' => ['nullable', 'string', 'max:255'],
'feature_github_oauth' => ['nullable', 'boolean'],
'github_client_id' => ['nullable', 'string', 'max:255'],
'github_client_secret' => ['nullable', 'string', 'max:255'],
'social_login_callback_url' => ['nullable', 'string', 'max:255'],
// Regional
'regional_timezone' => ['nullable', 'string', 'max:100'],
'regional_date_format' => ['nullable', 'string', 'max:20'],
'regional_time_format' => ['nullable', 'string', 'max:20'],
// Login Security
'login_max_attempts' => ['nullable', 'integer', 'min:1', 'max:20'],
'login_lockout_duration' => ['nullable', 'integer', 'min:1', 'max:1440'],
'login_lockout_notify' => ['nullable', 'boolean'],
'two_factor_auth' => ['nullable', 'boolean'],
'two_factor_method' => ['nullable', 'string', 'in:email,app'],
'captcha_enabled' => ['nullable', 'boolean'],
'captcha_site_key' => ['nullable', 'string', 'max:255'],
'captcha_secret_key' => ['nullable', 'string', 'max:255'],
'captcha_version' => ['nullable', 'string', 'in:v2,v3'],
'login_log_enabled' => ['nullable', 'boolean'],
// Password Policy
'password_min_length' => ['nullable', 'integer', 'min:8', 'max:100'],
'password_max_length' => ['nullable', 'integer', 'min:8', 'max:255'],
'password_require_uppercase' => ['nullable', 'boolean'],
'password_require_lowercase' => ['nullable', 'boolean'],
'password_require_numeric' => ['nullable', 'boolean'],
'password_require_special' => ['nullable', 'boolean'],
'password_expiry_days' => ['nullable', 'integer', 'min:0', 'max:365'],
'password_history_count' => ['nullable', 'integer', 'min:0', 'max:10'],
'password_reset_link_expiry' => ['nullable', 'integer', 'min:1', 'max:10080'],
// Session Security
'session_driver' => ['nullable', 'string', 'in:file,redis,database'],
'session_lifetime' => ['nullable', 'integer', 'min:1', 'max:10080'],
'session_single_session' => ['nullable', 'boolean'],
'session_auto_logout_idle' => ['nullable', 'integer', 'min:1', 'max:10080'],
'session_allow_remember_me' => ['nullable', 'boolean'],
'session_remember_me_duration' => ['nullable', 'integer', 'min:1', 'max:365'],
'session_secure_cookie' => ['nullable', 'boolean'],
'session_encrypt' => ['nullable', 'boolean'],
'session_concurrent_limit' => ['nullable', 'integer', 'min:0', 'max:50'],
// WebAuthn
'two_factor_trust_days' => ['nullable', 'integer', 'min:1', 'max:365'],
'webauthn_enabled' => ['nullable', 'boolean'],
// IP & Access Control
'ip_whitelist_admin' => ['nullable', 'string'],
'ip_blacklist' => ['nullable', 'string'],
'rate_limit_per_ip' => ['nullable', 'integer', 'min:1', 'max:1000'],
'auto_block_ip' => ['nullable', 'boolean'],
'threshold_auto_block' => ['nullable', 'integer', 'min:1', 'max:5000'],
'force_https' => ['nullable', 'boolean'],
'hsts_enabled' => ['nullable', 'boolean'],
'cors_origins' => ['nullable', 'string'],
'cors_methods' => ['nullable', 'string'],
'cors_headers' => ['nullable', 'string'],
// Notifications
'mail_driver' => ['nullable', 'string', 'in:smtp,mailgun,ses,mail'],
'mail_host' => ['nullable', 'string', 'max:255'],
'mail_port' => ['nullable', 'integer', 'min:1', 'max:65535'],
'mail_username' => ['nullable', 'string', 'max:255'],
'mail_password' => ['nullable', 'string', 'max:255'],
'mail_encryption' => ['nullable', 'string', 'in:tls,ssl,null'],
'mail_from_address' => ['nullable', 'email', 'max:255'],
'mail_from_name' => ['nullable', 'string', 'max:255'],
'telegram_bot_token' => ['nullable', 'string', 'max:255'],
'telegram_chat_id' => ['nullable', 'string', 'max:255'],
// Backups
'backup_db_enabled' => ['nullable', 'boolean'],
'backup_db_driver' => ['nullable', 'string', 'in:local,s3,gdrive'],
'backup_db_frequency' => ['nullable', 'string', 'in:hourly,daily,weekly,monthly'],
'backup_db_time' => ['nullable', 'string', 'regex:/^[0-9]{2}:[0-9]{2}$/'],
'backup_db_retention' => ['nullable', 'integer', 'min:1', 'max:365'],
'backup_db_compress' => ['nullable', 'boolean'],
'backup_db_encrypt' => ['nullable', 'boolean'],
'backup_db_encrypt_key' => ['nullable', 'string', 'min:32', 'max:255'],
'backup_db_exclude' => ['nullable', 'string'],
'backup_db_notify_on' => ['nullable', 'string', 'in:success,failed,both,none'],
'backup_db_notify_to' => ['nullable', 'string', 'max:255'],
// Google Drive Backups
'gdrive_client_id' => ['nullable', 'string', 'max:500'],
'gdrive_client_secret' => ['nullable', 'string', 'max:500'],
'gdrive_refresh_token' => ['nullable', 'string', 'max:1000'],
'gdrive_folder' => ['nullable', 'string', 'max:255'],
// S3 Backups
's3_key' => ['nullable', 'string', 'max:255'],
's3_secret' => ['nullable', 'string', 'max:255'],
's3_region' => ['nullable', 'string', 'max:100'],
's3_bucket' => ['nullable', 'string', 'max:255'],
's3_endpoint' => ['nullable', 'string', 'max:500'],
// Maintenance Mode
'maintenance_mode_enabled' => ['nullable', 'boolean'],
'maintenance_mode_message' => ['nullable', 'string', 'max:1000'],
'maintenance_mode_title' => ['nullable', 'string', 'max:200'],
'maintenance_mode_secret' => ['nullable', 'string', 'alpha_dash', 'max:100'],
'maintenance_mode_allowed_ips' => ['nullable', 'string'],
'maintenance_mode_end_at' => ['nullable', 'date'],
'maintenance_mode_retry' => ['nullable', 'integer', 'min:0', 'max:3600'],
'maintenance_mode_image' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],
// Content & Legal
'page_help_content' => ['nullable', 'string'],
'page_tos_content' => ['nullable', 'string'],
'page_privacy_content' => ['nullable', 'string'],
'page_about_content' => ['nullable', 'string'],
'page_security_content' => ['nullable', 'string'],
'require_pdp_on_registration' => ['nullable', 'boolean'],
'feature_cookie_banner' => ['nullable', 'boolean'],
'pdp_document_version' => ['nullable', 'integer', 'min:1'],
'tos_document_version' => ['nullable', 'integer', 'min:1'],
'pdp_dpo_email' => ['nullable', 'email', 'max:255'],
'pdp_company_address' => ['nullable', 'string', 'max:500'],
// AI Configuration
'ai_enabled' => ['nullable', 'boolean'],
'ai_provider' => ['nullable', 'string', 'in:gpt,gemini,claude,deepseek,grok,mistral,ollama,openrouter'],
'ai_gpt_key' => ['nullable', 'string', 'max:255'],
'ai_gemini_key' => ['nullable', 'string', 'max:255'],
'ai_claude_key' => ['nullable', 'string', 'max:255'],
'ai_deepseek_key' => ['nullable', 'string', 'max:255'],
'ai_grok_key' => ['nullable', 'string', 'max:255'],
'ai_mistral_key' => ['nullable', 'string', 'max:255'],
'ai_ollama_base_url' => ['nullable', 'string', 'max:255'],
'ai_openrouter_key' => ['nullable', 'string', 'max:255'],
'ai_default_model' => ['nullable', 'string', 'max:100'],
'ai_system_instruction' => ['nullable', 'string', 'max:5000'],
'ai_temperature' => ['nullable', 'numeric', 'min:0', 'max:2'],
'ai_max_tokens' => ['nullable', 'integer', 'min:1', 'max:32000'],
// SAP RFC Configuration
'sap_rfc_ashost' => ['nullable', 'string', 'max:255'],
'sap_rfc_sysnr' => ['nullable', 'string', 'max:20'],
'sap_rfc_client' => ['nullable', 'string', 'max:20'],
'sap_rfc_user' => ['nullable', 'string', 'max:255'],
'sap_rfc_passwd' => ['nullable', 'string', 'max:255'],
'sap_rfc_router' => ['nullable', 'string', 'max:255'],
'sap_rfc_trace' => ['nullable', 'string', 'in:0,1,2'],
'engine_pulse_enabled' => ['nullable', 'boolean'],
'engine_telescope_enabled' => ['nullable', 'boolean'],
'engine_swagger_enabled' => ['nullable', 'boolean'],
'engine_horizon_enabled' => ['nullable', 'boolean'],
'ai_healing_enabled' => ['nullable', 'boolean'],
];
}
protected function prepareForValidation(): void
{
$booleans = [
'feature_notification_center',
'feature_google_oauth',
'feature_facebook_oauth',
'feature_github_oauth',
'login_lockout_notify',
'two_factor_auth',
'captcha_enabled',
'login_log_enabled',
'password_require_uppercase',
'password_require_lowercase',
'password_require_numeric',
'password_require_special',
'webauthn_enabled',
'session_single_session',
'session_allow_remember_me',
'session_secure_cookie',
'session_encrypt',
'auto_block_ip',
'force_https',
'hsts_enabled',
'backup_db_enabled',
'backup_db_compress',
'backup_db_encrypt',
'maintenance_mode_enabled',
'require_pdp_on_registration',
'feature_cookie_banner',
'ai_enabled',
'enable_landing_page',
'engine_pulse_enabled',
'engine_telescope_enabled',
'engine_swagger_enabled',
'engine_horizon_enabled',
'ai_healing_enabled',
];
$updates = [];
foreach ($booleans as $key) {
$updates[$key] = $this->boolean($key);
}
if (!empty($updates)) {
$this->merge($updates);
}
}
}