149 lines
3.5 KiB
PHP
149 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use App\Models\User;
|
|
use Closure;
|
|
use Illuminate\Auth\Middleware\RedirectIfAuthenticated as BaseMiddleware;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
class RedirectIfAuthenticated extends BaseMiddleware
|
|
{
|
|
/**
|
|
* Handle an incoming request.
|
|
*/
|
|
public function handle(Request $request, Closure $next, string ...$guards): Response
|
|
{
|
|
$guards = $guards === [] ? [null] : $guards;
|
|
|
|
foreach ($guards as $guard) {
|
|
if (! Auth::guard($guard)->check()) {
|
|
continue;
|
|
}
|
|
|
|
$user = Auth::guard($guard)->user();
|
|
|
|
if ($this->shouldBypassForTenantAdmin($request, $user)) {
|
|
continue;
|
|
}
|
|
|
|
if ($user && $user->role === 'tenant_admin') {
|
|
$this->storeTenantAdminTarget($request);
|
|
}
|
|
|
|
return redirect($this->redirectPath($user));
|
|
}
|
|
|
|
return $next($request);
|
|
}
|
|
|
|
private function shouldBypassForTenantAdmin(Request $request, ?User $user): bool
|
|
{
|
|
if (! $user || $user->role !== 'tenant_admin') {
|
|
return false;
|
|
}
|
|
|
|
$encoded = $request->string('return_to')->trim()->toString();
|
|
|
|
if ($encoded === '') {
|
|
return false;
|
|
}
|
|
|
|
$decoded = $this->decodeReturnTo($encoded);
|
|
|
|
if ($decoded === null) {
|
|
return false;
|
|
}
|
|
|
|
$path = $this->normalizePath($decoded);
|
|
|
|
return str_starts_with($path, '/event-admin');
|
|
}
|
|
|
|
private function decodeReturnTo(string $value): ?string
|
|
{
|
|
$padded = str_pad($value, strlen($value) + ((4 - (strlen($value) % 4)) % 4), '=');
|
|
$normalized = strtr($padded, '-_', '+/');
|
|
$decoded = base64_decode($normalized, true);
|
|
|
|
return $decoded === false ? null : $decoded;
|
|
}
|
|
|
|
private function normalizePath(string $target): string
|
|
{
|
|
$trimmed = trim($target);
|
|
|
|
if ($trimmed === '') {
|
|
return '';
|
|
}
|
|
|
|
if (str_starts_with($trimmed, '/')) {
|
|
return $trimmed;
|
|
}
|
|
|
|
$parsed = parse_url($trimmed);
|
|
|
|
if ($parsed === false || ! isset($parsed['path'])) {
|
|
return '';
|
|
}
|
|
|
|
$path = $parsed['path'];
|
|
|
|
if (! str_starts_with($path, '/')) {
|
|
$path = '/'.$path;
|
|
}
|
|
|
|
if (isset($parsed['query'])) {
|
|
$path .= '?'.$parsed['query'];
|
|
}
|
|
|
|
if (isset($parsed['fragment'])) {
|
|
$path .= '#'.$parsed['fragment'];
|
|
}
|
|
|
|
return $path;
|
|
}
|
|
|
|
private function redirectPath(?User $user): string
|
|
{
|
|
if ($user && $user->role === 'tenant_admin') {
|
|
return '/event-admin/dashboard';
|
|
}
|
|
|
|
if ($user && $user->isSuperAdmin()) {
|
|
return '/super-admin';
|
|
}
|
|
|
|
if ($user && $user->role === 'user') {
|
|
return '/packages';
|
|
}
|
|
|
|
return '/dashboard';
|
|
}
|
|
|
|
private function storeTenantAdminTarget(Request $request): void
|
|
{
|
|
$encoded = $request->string('return_to')->trim()->toString();
|
|
|
|
if ($encoded === '') {
|
|
return;
|
|
}
|
|
|
|
$decoded = $this->decodeReturnTo($encoded);
|
|
|
|
if ($decoded === null) {
|
|
return;
|
|
}
|
|
|
|
$path = $this->normalizePath($decoded);
|
|
|
|
if (! str_starts_with($path, '/event-admin')) {
|
|
return;
|
|
}
|
|
|
|
$request->session()->put('tenant_admin.return_to', $path);
|
|
}
|
|
}
|