🆙 Forget data back 🆙

This commit is contained in:
Remco
2026-01-07 20:31:19 +01:00
parent acf2d7e661
commit 789b670f51
412 changed files with 66963 additions and 0 deletions
@@ -0,0 +1,18 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Http\Request;
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*/
#[\Override]
protected function redirectTo(Request $request): ?string
{
return $request->expectsJson() ? null : route('login');
}
}
@@ -0,0 +1,48 @@
<?php
namespace App\Http\Middleware;
use App\Models\User\Ban;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class BannedMiddleware
{
public function handle(Request $request, Closure $next): Response
{
$authenticated = Auth::check();
$ipBan = Ban::where('ip', '=', $request->ip())
->where('ban_expire', '>', time())
->whereIn('type', ['ip', 'machine'])
->orderByDesc('id')
->exists();
if ($request->is('logout')) {
return $next($request);
}
if (! $authenticated && ! $ipBan && $request->is('banned')) {
return to_route('login');
}
if ($ipBan && ! $request->is('banned')) {
return to_route('banned.show');
}
if ($authenticated) {
$accountBan = $request->user()?->ban;
if ($accountBan && ! $request->is('banned')) {
return to_route('banned.show');
}
if (! $ipBan && ! $accountBan && $request->is('banned')) {
return to_route('me.show');
}
}
return $next($request);
}
}
@@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
class EncryptCookies extends Middleware
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array<int, string>
*/
protected $except = [
//
];
}
@@ -0,0 +1,23 @@
<?php
namespace App\Http\Middleware;
use App\Services\FindRetrosService;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
/* Credits to Kani for this */
class FindRetrosMiddleware
{
public function handle(Request $request, Closure $next): Response
{
$findRetrosService = new FindRetrosService;
if (config('habbo.findretros.enabled') && ! $findRetrosService->checkHasVoted()) {
return redirect($findRetrosService->getRedirectUri());
}
return $next($request);
}
}
@@ -0,0 +1,30 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class ForceStaffTwoFactorMiddleware
{
public function handle(Request $request, Closure $next): Response
{
if (! Auth::check() || ! setting('force_staff_2fa')) {
return $next($request);
}
$user = $request->user();
$urls = [
'user/settings/two-factor',
'user/settings/2fa-verify',
];
if (($user->rank >= setting('min_staff_rank') && ! $user->two_factor_confirmed) && ! in_array(request()->path(), $urls)) {
return to_route('settings.two-factor');
}
return $next($request);
}
}
@@ -0,0 +1,159 @@
<?php
namespace App\Http\Middleware;
use App\Exceptions\MigrationFailedException;
use App\Models\Miscellaneous\WebsiteInstallation;
use Closure;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
class InstallationMiddleware
{
public function handle(Request $request, Closure $next)
{
if (Cache::get('app_installed')) {
return $next($request);
}
$this->ensureInstallationTableExists();
$installation = $this->getInstallation();
if ($installation && $installation->completed && $request->is('installation*')) {
Cache::rememberForever('app_installed', fn () => true);
return to_route('welcome');
}
$isInstallationStepHandled = $this->handleInstallationSteps($request, $installation);
if (! $isInstallationStepHandled) {
return $this->redirectIfNotCompleted($installation);
}
return $next($request);
}
private function ensureInstallationTableExists()
{
if (! Schema::hasTable('website_installation')) {
Artisan::call('migrate', ['--path' => 'database/migrations/' . findMigration('website_installation')]);
if (! Schema::hasTable('website_installation')) {
throw new MigrationFailedException('website_installation');
}
}
if (! Schema::hasTable('sessions')) {
Artisan::call('migrate', ['--path' => 'database/migrations/' . findMigration('sessions')]);
}
}
private function getInstallation()
{
try {
$installation = WebsiteInstallation::query()->first();
if (! $installation) {
return WebsiteInstallation::create([
'step' => 0,
'completed' => false,
'installation_key' => Str::uuid(),
'user_ip' => request()?->ip(),
]);
}
return $installation;
} catch (Exception $e) {
Log::error('Error fetching or creating WebsiteInstallation: ' . $e->getMessage());
abort(500, 'An error occurred while setting up the installation.');
}
}
private function handleInstallationSteps(Request $request, WebsiteInstallation $installation)
{
if ($installation->completed) {
return true;
}
if ($this->isWelcomeStep($request, $installation)) {
return true;
}
if ($this->isRedirectToWelcome($request, $installation)) {
return false;
}
if ($this->isInvalidAccess($request, $installation)) {
abort(403);
}
if ($this->isInvalidStep($request)) {
return false;
}
return ! $this->isMismatchedStep($request, $installation);
}
private function isWelcomeStep(Request $request, WebsiteInstallation $installation)
{
return $installation->step === 0 && $request->getRequestUri() === '/installation';
}
private function isRedirectToWelcome(Request $request, WebsiteInstallation $installation)
{
return $installation->step === 0 && $request->getRequestUri() !== '/installation' && $request->method() !== 'POST';
}
private function isInvalidAccess(Request $request, WebsiteInstallation $installation)
{
return $installation->step > 0 && $request->ip() !== $installation->user_ip;
}
private function isInvalidStep(Request $request)
{
return ! $this->isValidStep($request) && $this->isNonPostRequest($request);
}
private function isMismatchedStep(Request $request, WebsiteInstallation $installation)
{
return $this->getCurrentStep($request) !== $installation->step && $this->isNonPostRequest($request);
}
private function isValidStep(Request $request)
{
$step = $this->getCurrentStep($request);
return filter_var($step, FILTER_VALIDATE_INT) !== false;
}
private function isNonPostRequest(Request $request)
{
return $request->method() !== 'POST' || $request->is('restart-installation');
}
private function getCurrentStep(Request $request)
{
return (int) Str::after($request->path(), 'step/');
}
private function redirectToStep(int $step)
{
return to_route('installation.show-step', $step);
}
protected function redirectIfNotCompleted(WebsiteInstallation $installation)
{
if ($installation->step === 0) {
return to_route('installation.index');
}
return $this->redirectToStep($installation->step ?: 1);
}
}
@@ -0,0 +1,50 @@
<?php
namespace App\Http\Middleware;
use App\Models\Miscellaneous\WebsiteLanguage;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Session;
use Symfony\Component\HttpFoundation\Response;
class LocalizationMiddleware
{
public function handle(Request $request, Closure $next): Response
{
// Controleer of de instellingen bestaan en of de taal al in de sessie staat
if (Schema::hasTable('website_settings') && Session::has('locale')) {
App::setLocale(Session::get('locale'));
return $next($request);
}
$countryCode = config('habbo.site.default_language');
// GEWIJZIGD: isset() werkt niet op Request::server() in PHP 8. Gebruik null !== in plaats daarvan.
if (null !== \Illuminate\Support\Facades\Request::server('HTTP_CF_IPCOUNTRY')) {
$countryCode = strtolower((string) \Illuminate\Support\Facades\Request::server('HTTP_CF_IPCOUNTRY'));
}
elseif (null !== \Illuminate\Support\Facades\Request::server('HTTP_ACCEPT_LANGUAGE')) {
$countryCode = strtolower(substr((string) \Illuminate\Support\Facades\Request::server('HTTP_ACCEPT_LANGUAGE'), 0, 2));
}
// Als de taal niet in de database staat, gebruik de standaardtaal
if (Schema::hasTable('website_languages') && WebsiteLanguage::where('country_code', '=', $countryCode)->doesntExist()) {
$defaultCountry = config('habbo.site.default_language');
App::setLocale($defaultCountry);
Session::put('locale', $defaultCountry);
return $next($request);
}
// Zet de gedetecteerde taal
App::setLocale($countryCode);
Session::put('locale', $countryCode);
return $next($request);
}
}
@@ -0,0 +1,24 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class LogViewerMiddleware
{
public function handle(Request $request, Closure $next): Response
{
if (! Auth::check()) {
return to_route('login');
}
if (hasPermission('view_server_logs') === '' || hasPermission('view_server_logs') === '0') {
abort(403);
}
return $next($request);
}
}
@@ -0,0 +1,58 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class MaintenanceMiddleware
{
public function handle(Request $request, Closure $next): Response
{
$isPostRequest = $request->method() === 'POST';
$isMaintenanceRequest = $request->is('maintenance');
$maintenanceEnabled = setting('maintenance_enabled');
$fortify2faRoutes = [
'two-factor.login',
'two-factor.confirm',
];
if ($maintenanceEnabled && $isPostRequest && ! Auth::check()) {
return $next($request);
}
$isFortify2faRoute = in_array($request->route()?->getName(), $fortify2faRoutes, true);
if ($maintenanceEnabled && $isFortify2faRoute) {
return $next($request);
}
if (Auth::check() && Auth::user()->rank >= setting('min_maintenance_login_rank')) {
if ($isMaintenanceRequest) {
return to_route('me.show');
}
return $next($request);
}
if (Auth::check() && Auth::user()->rank >= setting('min_maintenance_login_rank') && $isMaintenanceRequest) {
return to_route('me.show');
}
if ($maintenanceEnabled && ! $isMaintenanceRequest && ! $isPostRequest) {
return to_route('maintenance.show');
}
if (! $maintenanceEnabled && $isMaintenanceRequest && ! $isPostRequest) {
return to_route('welcome');
}
if ($maintenanceEnabled && ! $isMaintenanceRequest && Auth::check() && Auth::user()->rank < setting('min_maintenance_login_rank')) {
return to_route('maintenance.show');
}
return $next($request);
}
}
@@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
class PreventRequestsDuringMaintenance extends Middleware
{
/**
* The URIs that should be reachable while maintenance mode is enabled.
*
* @var array<int, string>
*/
protected $except = [
//
];
}
@@ -0,0 +1,47 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class RealClientIpMiddleware
{
public function handle(Request $request, Closure $next)
{
$proxyHeaders = [
'HTTP_CF_CONNECTING_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_REAL_IP',
'HTTP_CLIENT_IP',
'HTTP_TRUE_CLIENT_IP',
];
foreach ($proxyHeaders as $header) {
if (! empty(\Illuminate\Support\Facades\Request::server($header))) {
$ip = \Illuminate\Support\Facades\Request::server($header);
if (str_contains((string) $ip, ',')) {
[$ip] = explode(',', (string) $ip);
}
$ip = trim((string) $ip);
if (filter_var($ip, FILTER_VALIDATE_IP)) {
// Set the real IP as REMOTE_ADDR
$request->server->set('REMOTE_ADDR', $ip);
break;
}
}
}
// Special handling for REMOTE_ADDR with multiple IPs
$remoteAddr = \Illuminate\Support\Facades\Request::server('REMOTE_ADDR') ?? '';
if (! empty($remoteAddr) && str_contains((string) $remoteAddr, ',')) {
[$ip] = explode(',', (string) $remoteAddr);
$ip = trim($ip);
if (filter_var($ip, FILTER_VALIDATE_IP)) {
$request->server->set('REMOTE_ADDR', $ip);
}
}
return $next($request);
}
}
@@ -0,0 +1,35 @@
<?php
namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param Closure(Request):((\Illuminate\Http\Response|RedirectResponse)) $next
*/
public function handle(Request $request, Closure $next, string ...$guards): Response
{
$guards = $guards === [] ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
if ($request->expectsJson()) {
return response()->json();
}
return redirect(RouteServiceProvider::HOME);
}
}
return $next($request);
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Qirolab\Theme\Theme;
use Symfony\Component\HttpFoundation\Response;
class SetThemeMiddleware
{
public function handle(Request $request, Closure $next): Response
{
if (setting('theme') === '' || setting('theme' === '1')) {
Theme::set('atom');
} else {
Theme::set(setting('theme'));
}
return $next($request);
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
class TrimStrings extends Middleware
{
/**
* The names of the attributes that should not be trimmed.
*
* @var array<int, string>
*/
protected $except = [
'current_password',
'password',
'password_confirmation',
];
}
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Middleware\TrustHosts as Middleware;
class TrustHosts extends Middleware
{
/**
* Get the host patterns that should be trusted.
*
* @return array<int, string|null>
*/
#[\Override]
public function hosts(): array
{
return [
$this->allSubdomainsOfApplicationUrl(),
];
}
}
@@ -0,0 +1,28 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array<int, string>|string|null
*/
protected $proxies;
/**
* The headers that should be used to detect proxies.
*
* @var int
*/
protected $headers =
Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB;
}
@@ -0,0 +1,81 @@
<?php
namespace App\Http\Middleware;
use App\Models\Miscellaneous\WebsiteIpBlacklist;
use App\Models\Miscellaneous\WebsiteIpWhitelist;
use App\Services\IpLookupService;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class VPNCheckerMiddleware
{
public function handle(Request $request, Closure $next): Response
{
// Skip check if vpn checker is disabled
if (setting('vpn_block_enabled') === '0' || setting('ipdata_api_key') === 'ADD-API-KEY-HERE') {
return $next($request);
}
// Skip check if the rank is allowed to bypass the checker
if (hasPermission('bypass_vpn') !== '' && hasPermission('bypass_vpn') !== '0') {
return $next($request);
}
// Skip check if the IP is in the whitelist table
if (WebsiteIpWhitelist::where('ip_address', $request->ip())->exists()) {
return $next($request);
}
// Restrict user if IP is blacklisted
if (WebsiteIpBlacklist::where('ip_address', $request->ip())->exists()) {
return to_route('me.show')->withErrors([
'message' => __('Your IP have been restricted - If you think this is a mistake, you can contact us on our Discord.'),
]);
}
// Instantiate the necessary things to look up the visitor IP
$ipService = new IpLookupService(setting('ipdata_api_key'));
$userIp = $request->ip();
$apiResponse = $ipService->ipLookup($userIp);
$asn = $apiResponse['asn']['asn'] ?? '';
$asnWhitelisted = WebsiteIpWhitelist::where('asn', $asn)
->where('whitelist_asn', '=', '1')
->exists();
if ($asnWhitelisted) {
return $next($request);
}
// Fetch all blacklisted ASNs
$asnBlacklisted = WebsiteIpBlacklist::where('asn', $asn)
->where('blacklist_asn', '=', '1')
->exists();
// Restrict the user if their ASN is within the blacklist table
if ($asnBlacklisted) {
return to_route('me.show')->withErrors([
'message' => __('Your IP have been restricted - If you think this is a mistake, you can contact us on our Discord.'),
]);
}
if (isset($apiResponse['threat']) && is_array($apiResponse['threat'])) {
$filteredThreats = array_diff_key($apiResponse['threat'], array_flip(['blocklists', 'is_icloud_relay', 'is_datacenter', 'is_tor', 'is_proxy']));
if (in_array(true, $filteredThreats, true)) {
WebsiteIpBlacklist::create([
'ip_address' => $userIp,
'asn' => null,
]);
return to_route('me.show')->withErrors([
'message' => __('Your IP has been restricted - If you think this is a mistake, you can contact us on our Discord.'),
]);
}
}
return $next($request);
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
class ValidateSignature extends Middleware
{
/**
* The names of the query string parameters that should be ignored.
*
* @var array<int, string>
*/
protected $except = [
// 'fbclid',
// 'utm_campaign',
// 'utm_content',
// 'utm_medium',
// 'utm_source',
// 'utm_term',
];
}
@@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array<int, string>
*/
protected $except = [
//
];
}