- Server di posta in Impostazioni (password cifrata, email di prova): se compilato prende il posto del .env; non si esporta e l'import XML non lo cancella. MAIL_SCHEME=tls nel .env.example non era valido per Laravel 11. - Proclamatori con email e telefono facoltativi, cifrati, nell'XML e cancellati dall'anonimizzazione; il numero apre WhatsApp. - Dopo l'assegnazione un riquadro in evidenza con il link del PDF, "Invia su WhatsApp" con il messaggio pronto e la scelta "inviato / non ancora", che resta finché non si sceglie. - Conferma dell'email obbligatoria per tutti gli utenti, anche esistenti: email in italiano, link valido senza login, nuova conferma a ogni cambio di indirizzo, "Reinvia conferma" in Utenti. Senza conferma restano raggiungibili profilo, cambio password e, per l'admin, il server di posta; comando utenti:conferma-email per l'emergenza. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
124 lines
5.5 KiB
PHP
124 lines
5.5 KiB
PHP
<?php
|
|
|
|
namespace App\Providers;
|
|
|
|
use App\Models\Setting;
|
|
use App\Services\ConfigurazionePosta;
|
|
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;
|
|
use Illuminate\Auth\Notifications\VerifyEmail;
|
|
use Illuminate\Notifications\Messages\MailMessage;
|
|
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(function () {
|
|
Setting::flushCache();
|
|
|
|
// Anche il server di posta: cambiato dal browser, il worker
|
|
// continuava a usare quello del primo invio.
|
|
if ($this->app->resolved('mail.manager')) {
|
|
app(ConfigurazionePosta::class)->applica();
|
|
}
|
|
});
|
|
|
|
// L'email di conferma in italiano. Il link resta quello di Laravel
|
|
// (firmato, scade dopo auth.verification.expire minuti) e porta a
|
|
// VerificaEmailController::conferma, che funziona anche senza login.
|
|
VerifyEmail::toMailUsing(function ($utente, string $link) {
|
|
$minuti = (int) config('auth.verification.expire', 60);
|
|
|
|
return (new MailMessage)
|
|
->subject('Conferma il tuo indirizzo email — TerManager2')
|
|
->greeting('Ciao ' . $utente->name . ',')
|
|
->line('per usare TerManager2 conferma che questo indirizzo email è tuo.')
|
|
->action('Conferma l\'indirizzo', $link)
|
|
->line("Il link vale {$minuti} minuti. Se è scaduto, entra in TerManager2 e chiedine uno nuovo.")
|
|
->line('Se non sai di cosa si tratta, ignora questa email.')
|
|
->salutation('TerManager2');
|
|
});
|
|
|
|
// Le richieste di Livewire non ripassano dal gruppo di rotte della
|
|
// pagina: senza, una scheda aperta prima del blocco continuerebbe a
|
|
// lavorare con un'email non confermata.
|
|
Livewire::addPersistentMiddleware([EnsureEmailIsVerified::class]);
|
|
|
|
// Il server di posta configurato in Impostazioni prende il posto di
|
|
// quello del .env, appena Laravel crea il sistema di posta.
|
|
$this->app->afterResolving('mail.manager', function ($manager) {
|
|
app(ConfigurazionePosta::class)->applica($manager);
|
|
});
|
|
|
|
// 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;
|
|
});
|
|
}
|
|
}
|