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:
121
app/Services/ConfigurazionePosta.php
Normal file
121
app/Services/ConfigurazionePosta.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Mail\MailManager;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Il server di posta configurato dall'applicazione (Impostazioni → Posta).
|
||||
*
|
||||
* Se in Impostazioni c'è un server, vale quello; altrimenti resta quello del
|
||||
* .env, come prima. La configurazione si applica quando Laravel crea il
|
||||
* sistema di posta (AppServiceProvider) e prima di ogni job della coda,
|
||||
* perché il worker vive a lungo e avrebbe tenuto quella del primo invio.
|
||||
*/
|
||||
class ConfigurazionePosta
|
||||
{
|
||||
public const CIFRATURA_AUTOMATICA = 'auto';
|
||||
|
||||
public const CIFRATURA_SSL = 'ssl';
|
||||
|
||||
public const CIFRATURA_NESSUNA = 'nessuna';
|
||||
|
||||
public const CIFRATURE = [
|
||||
self::CIFRATURA_AUTOMATICA => 'Automatica (STARTTLS se il server la offre, di solito porta 587)',
|
||||
self::CIFRATURA_SSL => 'SSL/TLS dall\'inizio (di solito porta 465)',
|
||||
self::CIFRATURA_NESSUNA => 'Nessuna (solo per server interni)',
|
||||
];
|
||||
|
||||
/** C'è un server di posta configurato dall'applicazione. */
|
||||
public function configurataNellApp(): bool
|
||||
{
|
||||
return trim((string) Setting::instance()->mail_host) !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Le email partono davvero: server dall'app, oppure un mailer del .env che
|
||||
* non sia "log" o "array" (che le scrivono nel log o le buttano).
|
||||
*/
|
||||
public function funzionante(): bool
|
||||
{
|
||||
if ($this->configurataNellApp()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$mailer = (string) config('mail.default');
|
||||
|
||||
return ! in_array($mailer, ['log', 'array'], true)
|
||||
&& ($mailer !== 'smtp' || trim((string) config('mail.mailers.smtp.host')) !== '');
|
||||
}
|
||||
|
||||
/** Porta la configurazione dell'app nel sistema di posta di Laravel. */
|
||||
public function applica(?MailManager $manager = null): void
|
||||
{
|
||||
try {
|
||||
$impostazioni = Setting::instance();
|
||||
} catch (\Throwable) {
|
||||
// Database non ancora pronto (prima installazione, migrazioni in
|
||||
// corso): resta il .env.
|
||||
return;
|
||||
}
|
||||
|
||||
if (trim((string) $impostazioni->mail_host) === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$password = $impostazioni->mail_password;
|
||||
} catch (DecryptException) {
|
||||
// Cifrata con un'altra APP_KEY: meglio tentare senza password (e
|
||||
// ricevere dal server un errore che dice "autenticazione") che
|
||||
// far cadere ogni pagina che tocca la posta.
|
||||
$password = null;
|
||||
}
|
||||
|
||||
$cifratura = $impostazioni->mail_cifratura ?: self::CIFRATURA_AUTOMATICA;
|
||||
|
||||
config([
|
||||
'mail.default' => 'smtp',
|
||||
'mail.mailers.smtp' => [
|
||||
'transport' => 'smtp',
|
||||
'scheme' => $cifratura === self::CIFRATURA_SSL ? 'smtps' : 'smtp',
|
||||
'host' => $impostazioni->mail_host,
|
||||
'port' => $impostazioni->mail_port ?: ($cifratura === self::CIFRATURA_SSL ? 465 : 587),
|
||||
'username' => $impostazioni->mail_username ?: null,
|
||||
'password' => $password ?: null,
|
||||
'timeout' => 20,
|
||||
'local_domain' => config('mail.mailers.smtp.local_domain'),
|
||||
// Senza, Symfony prova STARTTLS da solo appena il server lo offre.
|
||||
'auto_tls' => $cifratura !== self::CIFRATURA_NESSUNA,
|
||||
],
|
||||
'mail.from.address' => $impostazioni->mail_from_address ?: config('mail.from.address'),
|
||||
'mail.from.name' => $impostazioni->mail_from_name ?: ($impostazioni->congregazione_nome ?: config('mail.from.name')),
|
||||
]);
|
||||
|
||||
// Un mailer già creato tiene la configurazione con cui è nato.
|
||||
($manager ?? app('mail.manager'))->purge('smtp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Invia l'email di prova. Lancia RuntimeException con un messaggio
|
||||
* leggibile se il server rifiuta o non risponde.
|
||||
*/
|
||||
public function inviaProva(string $destinatario): void
|
||||
{
|
||||
$this->applica();
|
||||
|
||||
try {
|
||||
Mail::raw(
|
||||
"Questa è un'email di prova di TerManager2.\n\nSe la stai leggendo, il server di posta è configurato correttamente: "
|
||||
. 'gli utenti riceveranno le email per confermare il loro indirizzo.',
|
||||
fn ($messaggio) => $messaggio->to($destinatario)->subject('TerManager2 — email di prova'),
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
throw new RuntimeException('Il server di posta ha rifiutato l\'invio: ' . $e->getMessage(), 0, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user