*/ public array $data = []; public $blockedCountries; public $whitelistedIps; public $blacklistedIps; public $blocklistStats; public function mount(): void { $this->fillForm(); $this->loadData(); } protected function loadData(): void { $this->blockedCountries = WebsiteBlockedCountry::orderBy('country_name')->get(); $this->whitelistedIps = WebsiteIpWhitelist::orderBy('created_at', 'desc')->get(); $this->blacklistedIps = WebsiteIpBlacklist::orderBy('created_at', 'desc')->get(); $ipService = new IpLookupService(''); $this->blocklistStats = $ipService->getBlocklistStats(); } protected function fillForm(): void { $this->data = [ 'vpn_block_enabled' => $this->getSettingBool('vpn_block_enabled'), 'country_block_enabled' => $this->getSettingBool('country_block_enabled'), 'block_vpn' => $this->getSettingBool('block_vpn'), 'block_tor' => $this->getSettingBool('block_tor'), 'block_malicious' => $this->getSettingBool('block_malicious'), ]; } protected function getSetting(string $key, string $default = ''): string { return WebsiteSetting::where('key', $key)->first()?->value ?? $default; } protected function getSettingBool(string $key): bool { return WebsiteSetting::where('key', $key)->first()?->value === '1'; } public function form(Schema $schema): Schema { return $schema ->components([ Tabs::make('VPN Beheer') ->tabs([ Tab::make('Instellingen') ->icon('heroicon-o-cog-6-tooth') ->schema([ Section::make('Gratis Blokkering (Onbeperkt)') ->description('Gebruikt gratis community blocklists - geen API keys nodig') ->schema([ Toggle::make('data.vpn_block_enabled') ->label('VPN/TOR/Proxy Blokker Actief') ->helperText('Blokkeer VPN, TOR exit nodes, proxies en bekende malicious IPs'), ]), Section::make('Wat blokkeren?') ->schema([ Toggle::make('data.block_vpn') ->label('VPN & Proxies') ->helperText('FireHol blocklist'), Toggle::make('data.block_tor') ->label('TOR Exit Nodes') ->helperText('Alle bekende TOR exit nodes'), Toggle::make('data.block_malicious') ->label('Malicious IPs') ->helperText('Bekende kwaadwillende IPs uit community databases'), ]), Section::make('Land Blokkering') ->schema([ Toggle::make('data.country_block_enabled') ->label('Land Blokkering Actief') ->helperText('Sta alleen bezoekers uit toegestane landen toe'), ]), ]), Tab::make('Geblokkeerde Landen') ->icon('heroicon-o-globe-alt') ->schema([ Section::make('Land toevoegen') ->schema([ Select::make('country_to_block') ->label('Selecteer Land') ->options($this->getCountryOptions()) ->searchable() ->placeholder('Kies een land'), Action::make('addCountry') ->label('Blokkeer Land') ->action('addBlockedCountry') ->color('danger'), ]), ]), Tab::make('Whitelist') ->icon('heroicon-o-check-circle') ->schema([ Section::make('Whitelist toevoegen') ->schema([ TextInput::make('whitelist_ip') ->label('IP Adres') ->placeholder('192.168.1.1'), TextInput::make('whitelist_asn') ->label('ASN') ->placeholder('AS15169'), Select::make('whitelist_country') ->label('Land') ->options($this->getCountryOptions()) ->searchable(), Action::make('addToWhitelist') ->label('Toevoegen') ->action('addToWhitelist') ->color('success'), ]), ]), Tab::make('Blacklist') ->icon('heroicon-o-x-circle') ->schema([ Section::make('Blacklist toevoegen') ->schema([ TextInput::make('blacklist_ip') ->label('IP Adres') ->placeholder('192.168.1.1'), TextInput::make('blacklist_asn') ->label('ASN') ->placeholder('AS15169'), Select::make('blacklist_country') ->label('Land') ->options($this->getCountryOptions()) ->searchable(), Action::make('addToBlacklist') ->label('Toevoegen') ->action('addToBlacklist') ->color('danger'), ]), ]), Tab::make('IP Lookup') ->icon('heroicon-o-magnifying-glass') ->schema([ Section::make('IP Opzoeken') ->schema([ TextInput::make('lookup_ip') ->label('IP Adres') ->placeholder('Voer IP in om te controleren'), Action::make('lookupIp') ->label('Controleer') ->action('lookupIp') ->color('info'), ]), ]), Tab::make('Blocklist Stats') ->icon('heroicon-o-chart-bar') ->schema([ Section::make('Huidige Blocklists') ->description('Deze lijsten worden automatisch gedownload en dagelijks ververst') ->schema([ TextColumn::make('type')->label('Type'), TextColumn::make('count')->label('Aantal IPs'), ]), ]), ]), ]) ->statePath('data'); } protected function getCountryOptions(): array { return [ 'AD' => 'Andorra', 'AE' => 'United Arab Emirates', 'AF' => 'Afghanistan', 'AG' => 'Antigua and Barbuda', 'AI' => 'Anguilla', 'AL' => 'Albania', 'AM' => 'Armenia', 'AO' => 'Angola', 'AR' => 'Argentina', 'AT' => 'Austria', 'AU' => 'Australia', 'AW' => 'Aruba', 'AZ' => 'Azerbaijan', 'BA' => 'Bosnia and Herzegovina', 'BB' => 'Barbados', 'BD' => 'Bangladesh', 'BE' => 'Belgium', 'BG' => 'Bulgaria', 'BH' => 'Bahrain', 'BI' => 'Burundi', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BN' => 'Brunei', 'BO' => 'Bolivia', 'BR' => 'Brazil', 'BS' => 'Bahamas', 'BT' => 'Bhutan', 'BW' => 'Botswana', 'BY' => 'Belarus', 'BZ' => 'Belize', 'CA' => 'Canada', 'CH' => 'Switzerland', 'CL' => 'Chile', 'CN' => 'China', 'CO' => 'Colombia', 'CR' => 'Costa Rica', 'CU' => 'Cuba', 'CY' => 'Cyprus', 'CZ' => 'Czechia', 'DE' => 'Germany', 'DK' => 'Denmark', 'DO' => 'Dominican Republic', 'DZ' => 'Algeria', 'EC' => 'Ecuador', 'EE' => 'Estonia', 'EG' => 'Egypt', 'ES' => 'Spain', 'ET' => 'Ethiopia', 'FI' => 'Finland', 'FJ' => 'Fiji', 'FR' => 'France', 'GB' => 'United Kingdom', 'GD' => 'Grenada', 'GE' => 'Georgia', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GL' => 'Greenland', 'GM' => 'Gambia', 'GN' => 'Guinea', 'GR' => 'Greece', 'GT' => 'Guatemala', 'HK' => 'Hong Kong', 'HN' => 'Honduras', 'HR' => 'Croatia', 'HU' => 'Hungary', 'ID' => 'Indonesia', 'IE' => 'Ireland', 'IL' => 'Israel', 'IN' => 'India', 'IQ' => 'Iraq', 'IR' => 'Iran', 'IS' => 'Iceland', 'IT' => 'Italy', 'JM' => 'Jamaica', 'JO' => 'Jordan', 'JP' => 'Japan', 'KE' => 'Kenya', 'KH' => 'Cambodia', 'KR' => 'South Korea', 'KW' => 'Kuwait', 'KZ' => 'Kazakhstan', 'LA' => 'Laos', 'LB' => 'Lebanon', 'LK' => 'Sri Lanka', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'LV' => 'Latvia', 'MA' => 'Morocco', 'MC' => 'Monaco', 'MD' => 'Moldova', 'ME' => 'Montenegro', 'MG' => 'Madagascar', 'MK' => 'North Macedonia', 'MM' => 'Myanmar', 'MN' => 'Mongolia', 'MO' => 'Macao', 'MT' => 'Malta', 'MU' => 'Mauritius', 'MV' => 'Maldives', 'MX' => 'Mexico', 'MY' => 'Malaysia', 'MZ' => 'Mozambique', 'NA' => 'Namibia', 'NG' => 'Nigeria', 'NI' => 'Nicaragua', 'NL' => 'Netherlands', 'NO' => 'Norway', 'NP' => 'Nepal', 'NZ' => 'New Zealand', 'OM' => 'Oman', 'PA' => 'Panama', 'PE' => 'Peru', 'PH' => 'Philippines', 'PK' => 'Pakistan', 'PL' => 'Poland', 'PR' => 'Puerto Rico', 'PT' => 'Portugal', 'PY' => 'Paraguay', 'QA' => 'Qatar', 'RO' => 'Romania', 'RS' => 'Serbia', 'RU' => 'Russia', 'RW' => 'Rwanda', 'SA' => 'Saudi Arabia', 'SC' => 'Seychelles', 'SD' => 'Sudan', 'SE' => 'Sweden', 'SG' => 'Singapore', 'SI' => 'Slovenia', 'SK' => 'Slovakia', 'SN' => 'Senegal', 'SO' => 'Somalia', 'SR' => 'Suriname', 'SV' => 'El Salvador', 'SY' => 'Syria', 'TH' => 'Thailand', 'TJ' => 'Tajikistan', 'TN' => 'Tunisia', 'TR' => 'Turkey', 'TT' => 'Trinidad and Tobago', 'TW' => 'Taiwan', 'TZ' => 'Tanzania', 'UA' => 'Ukraine', 'UG' => 'Uganda', 'US' => 'United States', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VE' => 'Venezuela', 'VN' => 'Vietnam', 'ZA' => 'South Africa', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe', ]; } public function save(): void { $settings = [ 'vpn_block_enabled' => $this->data['vpn_block_enabled'] ? '1' : '0', 'country_block_enabled' => $this->data['country_block_enabled'] ? '1' : '0', 'block_vpn' => $this->data['block_vpn'] ?? true ? '1' : '0', 'block_tor' => $this->data['block_tor'] ?? true ? '1' : '0', 'block_malicious' => $this->data['block_malicious'] ?? true ? '1' : '0', ]; foreach ($settings as $key => $value) { WebsiteSetting::updateOrCreate(['key' => $key], ['value' => $value]); } Notification::make()->title(__('Saved'))->success()->send(); } public function refreshBlocklists(): void { $ipService = new IpLookupService(''); $ipService->refreshBlocklists(); $this->loadData(); Notification::make()->title('Blocklists vernieuwd')->success()->send(); } public function addBlockedCountry(): void { $countryCode = $this->data['country_to_block'] ?? null; if (! $countryCode) { Notification::make()->title('Selecteer een land')->danger()->send(); return; } if (WebsiteBlockedCountry::where('country_code', $countryCode)->exists()) { Notification::make()->title('Land is al geblokkeerd')->warning()->send(); return; } $countries = $this->getCountryOptions(); $countryCode = (string) $countryCode; WebsiteBlockedCountry::create([ 'country_code' => $countryCode, 'country_name' => $countries[$countryCode] ?? $countryCode, ]); $this->loadData(); Notification::make()->title('Land geblokkeerd')->success()->send(); } public function removeBlockedCountry(int $id): void { WebsiteBlockedCountry::destroy($id); $this->loadData(); Notification::make()->title('Verwijderd')->success()->send(); } public function addToWhitelist(): void { $ip = $this->data['whitelist_ip'] ?? null; $asn = $this->data['whitelist_asn'] ?? null; $countryCode = $this->data['whitelist_country'] ?? null; if (! $ip && ! $asn && ! $countryCode) { Notification::make()->title('Voer IP, ASN of land in')->danger()->send(); return; } $countries = $this->getCountryOptions(); $countryCodeStr = (string) ($countryCode ?? ''); $countryName = $countryCode ? ($countries[$countryCodeStr] ?? null) : null; WebsiteIpWhitelist::create([ 'ip_address' => $ip ?? null, 'asn' => $asn ?? null, 'country_code' => $countryCodeStr, 'country_name' => $countryName, 'whitelist_asn' => ! empty($asn), 'whitelist_country' => ! empty($countryCode), ]); $this->loadData(); Notification::make()->title('Toegevoegd aan whitelist')->success()->send(); } public function addToBlacklist(): void { $ip = $this->data['blacklist_ip'] ?? null; $asn = $this->data['blacklist_asn'] ?? null; $countryCode = $this->data['blacklist_country'] ?? null; if (! $ip && ! $asn && ! $countryCode) { Notification::make()->title('Voer IP, ASN of land in')->danger()->send(); return; } $countries = $this->getCountryOptions(); $countryCodeStr = (string) ($countryCode ?? ''); $countryName = $countryCode ? ($countries[$countryCodeStr] ?? null) : null; WebsiteIpBlacklist::create([ 'ip_address' => $ip ?? null, 'asn' => $asn ?? null, 'country_code' => $countryCodeStr, 'country_name' => $countryName, 'blacklist_asn' => ! empty($asn), 'blacklist_country' => ! empty($countryCode), ]); $this->loadData(); Notification::make()->title('Toegevoegd aan blacklist')->success()->send(); } public function removeFromWhitelist(int $id): void { WebsiteIpWhitelist::destroy($id); $this->loadData(); Notification::make()->title('Verwijderd')->success()->send(); } public function removeFromBlacklist(int $id): void { WebsiteIpBlacklist::destroy($id); $this->loadData(); Notification::make()->title('Verwijderd')->success()->send(); } public function lookupIp(): void { $ip = $this->data['lookup_ip'] ?? null; if (! $ip) { Notification::make()->title('Voer een IP in')->danger()->send(); return; } $ipService = new IpLookupService(''); $countryInfo = $ipService->getCountryInfo($ip); $threatInfo = $ipService->checkVpnProxyTor($ip); $message = "IP: {$ip}\n\n"; if (! empty($countryInfo['country_name'])) { $message .= "📍 {$countryInfo['country_name']} ({$countryInfo['country_code']})\n"; $message .= " {$countryInfo['city']} - {$countryInfo['isp']}\n\n"; } $message .= "🚫 Blokkeren:\n"; $message .= ' VPN/Proxy: ' . ($threatInfo['is_vpn'] ? 'JA' : 'Nee') . "\n"; $message .= ' TOR: ' . ($threatInfo['is_tor'] ? 'JA' : 'Nee') . "\n"; $message .= ' Malicious: ' . ($threatInfo['is_malicious'] ? 'JA' : 'Nee') . "\n"; Notification::make()->title('Resultaat')->body($message)->success()->send(); } #[\Override] protected function getActions(): array { return [ Action::make('save')->label('Opslaan')->action('save')->color('primary'), Action::make('refreshBlocklists')->label('Vernieuw Blocklists')->action('refreshBlocklists')->color('warning'), ]; } }