'required|min:1|numeric', 'thumbnail_max_h' => 'numeric|max:500|min:25', 'google_client_id' => 'nullable|ends_with:apps.googleusercontent.com', ]; protected $fillable = [ 'site_name', 'email_domain', 'email_format', 'username_format', 'webhook_endpoint', 'webhook_channel', 'webhook_botname', 'google_login', 'google_client_id', 'google_client_secret', 'manager_view_enabled', ]; protected $casts = [ 'label2_asset_logo' => 'boolean', 'require_checkinout_notes' => 'boolean', 'manager_view_enabled' => 'boolean', 'block_api_user_agents' => 'boolean', 'block_blank_api_user_agents' => 'boolean', // tinyInteger with no cast was leaking 0 (int) into call sites that // use loose-equality string checks like `== '1'` and `== ''`. Under // PHP 8 `0 == ''` is false, so checks expecting "disabled" misfired. // Normalize on read so every consumer sees a consistent string mode. 'two_factor_enabled' => 'string', ]; /** * Suggested defaults for the "blocked API User-Agent patterns" textarea. * * Substrings (matched case-insensitively against the request's User-Agent) * that identify common scripted or default HTTP clients. New installs see * this list as the pre-filled textarea value; admins can add, remove, or * blank it out entirely. Browser-driven AJAX (snipeit.js, datatables, * select2, etc.) carries the browser's own User-Agent and is unaffected. */ public const DEFAULT_BLOCKED_API_USER_AGENTS = [ 'curl/', 'wget/', 'python-requests/', 'python-urllib', 'PostmanRuntime/', 'insomnia/', 'Go-http-client/', 'okhttp/', 'HTTPie/', 'Apache-HttpClient/', 'Java/', 'Faraday', 'http.rb/', 'libwww-perl/', 'Ruby', 'node-fetch/', 'axios/', 'GuzzleHttp/', 'RestSharp/', ]; /** * Get the app settings. * Cache is expired on Setting model saved in EventServiceProvider. * * @author Wes Hulette * * @since 5.0.0 */ public static function getSettings(): ?self { if (! self::$_cache) { // Need for setup as no tables exist try { self::$_cache = self::first(); } catch (\Throwable $th) { return null; } } return self::$_cache; } /** * Check to see if setup process is complete. * Cache is expired on Setting model saved in EventServiceProvider. */ public static function setupCompleted(): bool { try { $usercount = User::withTrashed()->count(); $settingsCount = self::count(); return $usercount > 0 && $settingsCount > 0; } catch (\Throwable $th) { Log::debug('User table and settings table DO NOT exist or DO NOT have records'); // Catch the error if the tables dont exit return false; } } /** * Get the current Laravel version. */ public function lar_ver(): string { $app = App::getFacadeApplication(); return $app::VERSION; } /** * Get the default EULA text. */ public static function getDefaultEula(): ?string { if (self::getSettings()->default_eula_text) { return Helper::parseEscapedMarkedown(self::getSettings()->default_eula_text); } return null; } /** * Check wether to show in model dropdowns. * * @param string $element */ public function modellistCheckedValue($element): bool { $settings = self::getSettings(); // If the value is blank for some reason if ($settings->modellist_displays == '') { return false; } $values = explode(',', $settings->modellist_displays); foreach ($values as $value) { if ($value == $element) { return true; } } return false; } /** * Escapes the custom CSS, and then un-escapes the greater-than symbol * so it can work with direct descendant characters for bootstrap * menu overrides like:. * * .skin-blue .sidebar-menu>li.active>a, .skin-blue .sidebar-menu>li:hover>a * * Important: Do not remove the e() escaping here, as we output raw in the blade. * * @author A. Gianotto * * @return Attribute */ protected function headerColor(): Attribute { return Attribute::make( get: fn (?string $value) => CssColor::sanitize($value, '#3c8dbc'), ); } /** * @return Attribute */ protected function linkLightColor(): Attribute { return Attribute::make( get: fn (?string $value) => CssColor::sanitize($value, '#296282'), ); } /** * @return Attribute */ protected function linkDarkColor(): Attribute { return Attribute::make( get: fn (?string $value) => CssColor::sanitize($value, '#5fa4cc'), ); } /** * @return Attribute */ protected function navLinkColor(): Attribute { return Attribute::make( get: fn (?string $value) => CssColor::sanitize($value, '#ffffff'), ); } public function show_custom_css(): string { $custom_css = self::getSettings()->custom_css; if ($custom_css === null || $custom_css === '') { return ''; } // Superuser-planted CSS renders inside