Files
termanager2/app/Providers/AppServiceProvider.php
Francesco Picone 426a95211d Revisione blocchi 2 e 3: file protetti, ripristino atomico, import sicuri
Blocco 2
- Esiti delle azioni Livewire come avvisi (trait Avvisa) invece di flash
  che comparivano alla pagina dopo.
- PDF, miniature e versioni dei territori non più serviti da nginx su
  /storage: TerritorioFileController con login, permessi e cache privata.
- Ripristino tutto o niente: verifica dell'archivio, una transazione con
  import, piantine, blocco account e scambio dei file annullabile.
- Backup formato 2 con piantine, storico PDF e area KML.
- Posto unico preso in un passo (Cache::lock) e rispettato anche da
  import XML e PDF.
- Import PDF da cartella: abbinamento corretto (1-A, 12 B, ambigui),
  caricamento a lotti, file non PDF ignorati, PDF sostituito nello storico.
- L'import XML elimina i file dei territori che non usa più; comando
  territori:file-orfani per quelli accumulati prima.

Blocco 3
- Password attuale richiesta al cambio volontario; AuthenticateSession
  chiude le sessioni aperte altrove.
- Niente nomi dei proclamatori in chiaro nel registro attività.
- Export XML senza remember_token; chi riceve l'hash dal file deve
  cambiare password.
- Campagne: ultimo giorno incluso, percentuale sui territori distinti.
- Coda: retry_after 960 s, stop_grace_period 16m, Redis volatile-lru,
  impostazioni rilette a ogni job.
- Azzeramento che cancella anche piantine, area KML e anteprime.
- Pulsanti profilo e menu che non si nascondevano; icona del sito.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 15:01:41 +02:00

85 lines
3.5 KiB
PHP

<?php
namespace App\Providers;
use App\Models\Setting;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\URL;
use Livewire\Livewire;
use RuntimeException;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
//
}
public function boot(): void
{
// Setting tiene le impostazioni in una variabile statica, svuotata
// solo quando le salva lo stesso processo. Il worker resta vivo fino a
// un'ora: senza questo, ogni job usava le impostazioni lette dal primo,
// anche dopo che l'amministratore le aveva cambiate dal browser o un
// ripristino le aveva sostituite.
Queue::before(fn () => Setting::flushCache());
// Pin generated URLs to APP_URL.
//
// Behind a trusted proxy, Symfony derives the port from
// X-Forwarded-Port and falls back to the scheme's default when that
// header is absent — which silently drops a non-standard port from
// every generated link. Anchoring the root to APP_URL makes the
// public address explicit instead of reconstructed per request, and
// keeps PDF/e-mail links correct regardless of proxy behaviour.
$appUrl = (string) config('app.url');
if ($appUrl !== '') {
URL::forceRootUrl($appUrl);
if (str_starts_with($appUrl, 'https://')) {
URL::forceScheme('https');
}
}
// NOTE: APP_KEY is deliberately NOT auto-generated here.
//
// This provider boots on every request. Generating a key at runtime
// meant that if the key ever failed to persist, each request could
// mint a *different* one — and since proclamatori names are encrypted
// at column level with APP_KEY, every row written under a superseded
// key becomes permanently unreadable.
//
// The key is now resolved once at container start (docker/php/
// entrypoint.sh) and persisted to the storage volume. Fail loudly
// instead of silently rotating.
// Only enforced when serving HTTP. Build-time tooling (package:discover,
// config:cache) legitimately runs before the key exists, and failing
// there would break the image build rather than surface a real problem.
if (empty(config('app.key')) && ! $this->app->runningInConsole()) {
throw new RuntimeException(
'APP_KEY is not set. Set it in the environment before starting the application. '
.'Generate one with: php artisan key:generate --show'
);
}
// Livewire only re-applies a fixed allow-list of middleware to
// /livewire/update requests. Spatie's permission middleware is not on
// that list, so a component whose route is guarded by
// `permission:territori.manage` would keep accepting mutating actions
// from a user whose permission was revoked after page load, until they
// reload. Registering them as persistent closes that window.
Livewire::addPersistentMiddleware([
\Spatie\Permission\Middleware\PermissionMiddleware::class,
\Spatie\Permission\Middleware\RoleMiddleware::class,
\Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
]);
Gate::before(function ($user, $ability) {
return $user->hasRole('amministratore') ? true : null;
});
}
}