68 lines
2.2 KiB
PHP
68 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use App\Services\BackendHttpClient;
|
|
use Closure;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
class EnforceRestriction
|
|
{
|
|
public function __construct(private readonly BackendHttpClient $client)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Handle an incoming request.
|
|
* @param array<int,string> $types One or more restriction types to check
|
|
*/
|
|
public function handle(Request $request, Closure $next, ...$types)
|
|
{
|
|
$user = $request->user();
|
|
if (!$user) {
|
|
return $next($request);
|
|
}
|
|
|
|
if (empty($types)) {
|
|
$types = ['account_ban'];
|
|
}
|
|
|
|
try {
|
|
// Ask upstream whether any of the requested types are active for the current user
|
|
$query = ['types' => implode(',', $types)];
|
|
$res = $this->client->get($request, '/users/me/restrictions/check', $query, retry: true);
|
|
if ($res->successful()) {
|
|
$json = $res->json() ?: [];
|
|
$data = $json['data'] ?? $json; // support either {data:{...}} or flat map
|
|
$isRestricted = false;
|
|
$hitType = null;
|
|
foreach ($types as $t) {
|
|
if (!empty($data[$t])) { $isRestricted = true; $hitType = $t; break; }
|
|
}
|
|
|
|
if ($isRestricted) {
|
|
// For web requests: log out if account is banned and block access
|
|
if (!$request->expectsJson() && in_array('account_ban', $types, true)) {
|
|
Auth::logout();
|
|
$request->session()->invalidate();
|
|
$request->session()->regenerateToken();
|
|
}
|
|
|
|
$payload = [
|
|
'message' => 'Access is restricted for this action.',
|
|
'type' => $hitType,
|
|
];
|
|
|
|
return response()->json($payload, 403);
|
|
}
|
|
}
|
|
// On client/server error we fail open to avoid locking out users due to upstream outage
|
|
} catch (\Throwable $e) {
|
|
// swallow and continue
|
|
}
|
|
|
|
return $next($request);
|
|
}
|
|
}
|