feat: add app and database modules
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Services\Notification\TelegramService;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class IpAccessControl
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Closure(Request): (Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
$ip = $request->ip();
|
||||
|
||||
// Batch get common settings to reduce function overhead
|
||||
$settings = [
|
||||
'blacklist' => get_setting('ip_blacklist', ''),
|
||||
'whitelist_admin' => get_setting('ip_whitelist_admin', ''),
|
||||
'auto_block' => get_setting('auto_block_ip', false),
|
||||
'single_session' => get_setting('session_single_session', false),
|
||||
'hsts' => get_setting('hsts_enabled', false),
|
||||
];
|
||||
|
||||
// 1. GLOBAL BLACKLIST
|
||||
$blacklistArr = array_filter(array_map('trim', explode(',', $settings['blacklist'])));
|
||||
if (in_array($ip, $blacklistArr)) {
|
||||
abort(403, 'Your IP address has been blocked.');
|
||||
}
|
||||
|
||||
// 2. ADMIN WHITELIST (Protects specific routes)
|
||||
// Check if current route is an admin/restricted route
|
||||
if ($request->is('system-config*') || $request->is('users*') || $request->is('roles*') || $request->is('permissions*') || $request->is('backups*') || $request->is('admin/*')) {
|
||||
$whitelistArr = array_filter(array_map('trim', explode(',', $settings['whitelist_admin'])));
|
||||
if (! empty($whitelistArr) && ! in_array($ip, $whitelistArr)) {
|
||||
abort(403, 'Access denied: Admin IP Whitelist restricted.');
|
||||
}
|
||||
}
|
||||
|
||||
// 3. RATE LIMITING & AUTO BLOCK
|
||||
if ($settings['auto_block']) {
|
||||
$cacheKey = "ip_block:{$ip}";
|
||||
if (Cache::has($cacheKey)) {
|
||||
abort(429, 'Your IP has been temporarily blocked due to excessive requests.');
|
||||
}
|
||||
|
||||
$threshold = get_setting('threshold_auto_block', 100);
|
||||
|
||||
$hitKey = "ip_hits:{$ip}";
|
||||
Cache::add($hitKey, 0, now()->addMinute());
|
||||
$hits = Cache::increment($hitKey);
|
||||
|
||||
if ($hits > $threshold) {
|
||||
Cache::put($cacheKey, true, now()->addHours(24));
|
||||
|
||||
// 🚨 Send Security Alert to Telegram
|
||||
try {
|
||||
$telegram = app(TelegramService::class);
|
||||
$msg = "<b>[FIREWALL BLOCK]</b>\n\n";
|
||||
$msg .= "IP Address: <code>{$ip}</code>\n";
|
||||
$msg .= "Reason: <b>Excessive Requests</b> ({$hits} hits)\n";
|
||||
$msg .= "Action: <b>Auto-Blocked (24h)</b>\n\n";
|
||||
$msg .= "Check configuration: <a href='".url('/system-config')."'>Admin Panel</a>";
|
||||
$telegram->sendMessage($msg);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error('Firewall Telegram Alert Failed: '.$e->getMessage());
|
||||
}
|
||||
|
||||
abort(429, 'Excessive requests detected. Your IP has been blocked for 24 hours.');
|
||||
}
|
||||
}
|
||||
|
||||
// 4. SINGLE SESSION ENFORCEMENT
|
||||
// Skip check if we are currently impersonating to prevent logout
|
||||
if ($request->user() && $settings['single_session'] && ! session()->has('impersonator_id')) {
|
||||
if ($request->user()->last_session_id !== session()->getId()) {
|
||||
Auth::logout();
|
||||
|
||||
return redirect()->route('login')->with('error', 'You have been logged out because another device logged into your account.');
|
||||
}
|
||||
}
|
||||
|
||||
$response = $next($request);
|
||||
|
||||
// 5. HSTS (Transport Security)
|
||||
if ($request->isSecure() && $settings['hsts']) {
|
||||
$response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user