Posta configurabile dall'app, contatti dei proclamatori, conferma email

- 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>
This commit is contained in:
2026-10-12 17:12:31 +02:00
parent e7148c7b32
commit fc8623f7db
35 changed files with 1737 additions and 14 deletions

View File

@@ -0,0 +1,77 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Services\ConfigurazionePosta;
use Illuminate\Auth\Events\Verified;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
/**
* Conferma dell'indirizzo email degli utenti.
*
* Finché l'indirizzo non è confermato l'account non funziona: il middleware
* `verified` porta qui. Il link della mail funziona anche senza essere
* entrati: lo si apre spesso dal telefono, dove la sessione non c'è, e la
* firma dell'indirizzo (con scadenza) basta a garantire che venga dalla mail.
*/
class VerificaEmailController extends Controller
{
public function avviso(Request $request, ConfigurazionePosta $posta)
{
if ($request->user()->hasVerifiedEmail()) {
return redirect()->route('dashboard');
}
return view('auth.verifica-email', [
'user' => $request->user(),
'postaFunzionante' => $posta->funzionante(),
]);
}
public function invia(Request $request)
{
$user = $request->user();
if ($user->hasVerifiedEmail()) {
return redirect()->route('dashboard');
}
try {
$user->sendEmailVerificationNotification();
} catch (\Throwable $e) {
Log::warning('Email di conferma non inviata.', ['user' => $user->id, 'exception' => $e]);
return back()->with('error', 'L\'email non è partita: il server di posta non risponde o rifiuta l\'invio. Avvisa un amministratore.');
}
return back()->with('success', "Email inviata a {$user->email}. Apri il link che contiene (controlla anche lo spam).");
}
public function conferma(Request $request, int $id, string $hash)
{
$user = User::find($id);
// La firma garantisce id e scadenza; l'hash lega il link all'indirizzo
// di allora, così un link vecchio non conferma un'email cambiata dopo.
if (! $user || ! hash_equals(sha1($user->getEmailForVerification()), $hash)) {
abort(403, 'Link di conferma non valido.');
}
if (! $user->hasVerifiedEmail()) {
$user->markEmailAsVerified();
event(new Verified($user));
activity()->causedBy($user)->log('email_confermata');
}
$messaggio = 'Indirizzo email confermato.';
if ($request->user()?->is($user)) {
return redirect()->route('dashboard')->with('success', $messaggio);
}
return redirect()->route('login')->with('success', $messaggio . ' Ora puoi accedere.');
}
}