Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer collective, backed by the Pireon OAuth identity server. The public site is a separate, server-rendered application consuming /api/public/v1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
62 lines
2.0 KiB
PHP
62 lines
2.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use App\Support\Maintenance;
|
|
use Closure;
|
|
use Illuminate\Http\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
/**
|
|
* Answers 503 on the public API while the site is in maintenance.
|
|
*
|
|
* Applied only to `/api/public/*`, never to the panel or the admin API: the
|
|
* collective must be able to keep working — and to fix whatever caused the
|
|
* maintenance — while visitors see the notice.
|
|
*
|
|
* The body carries the translated message so the frontend can render a proper
|
|
* maintenance page from it rather than having to hardcode one.
|
|
*/
|
|
class EnsureSiteIsAvailable
|
|
{
|
|
public function handle(Request $request, Closure $next): Response
|
|
{
|
|
if (! Maintenance::isEnabled() || $this->mayBypass($request)) {
|
|
return $next($request);
|
|
}
|
|
|
|
$until = Maintenance::until();
|
|
|
|
return response()->json([
|
|
'message' => Maintenance::message(),
|
|
'maintenance' => true,
|
|
'locale' => app()->getLocale(),
|
|
'since' => Maintenance::startedAt()?->toIso8601String(),
|
|
'until' => $until?->toIso8601String(),
|
|
], Response::HTTP_SERVICE_UNAVAILABLE, [
|
|
'Retry-After' => (string) Maintenance::retryAfter(),
|
|
// 503 must never be cached, or the notice would outlive the
|
|
// maintenance itself.
|
|
'Cache-Control' => 'no-store, private',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* The team still sees the real site.
|
|
*
|
|
* The preview secret already means "I am the frontend acting for someone
|
|
* trusted", and the frontend's own address is equally trusted — so both
|
|
* pass straight through and can verify the fix before lifting the flag.
|
|
*/
|
|
protected function mayBypass(Request $request): bool
|
|
{
|
|
if ($request->attributes->get('preview', false)) {
|
|
return true;
|
|
}
|
|
|
|
return in_array($request->ip(), (array) config('site.trusted_ips'), true);
|
|
}
|
|
}
|