2026-05-26 08:14:29 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
|
|
2026-06-17 13:50:41 +02:00
|
|
|
use App\Enums\GoogleService;
|
2026-05-26 08:14:29 +02:00
|
|
|
use App\Http\Controllers\Controller;
|
2026-06-02 22:30:49 +02:00
|
|
|
use App\Models\EmailAttachment;
|
|
|
|
|
use App\Models\EmailFolder;
|
2026-05-26 08:14:29 +02:00
|
|
|
use App\Models\EmailSetting;
|
2026-05-27 07:29:29 +02:00
|
|
|
use App\Models\SenderAccount;
|
2026-06-17 13:50:41 +02:00
|
|
|
use App\Services\GoogleOAuthService;
|
2026-06-02 22:18:29 +02:00
|
|
|
use Illuminate\Http\RedirectResponse;
|
2026-05-26 08:14:29 +02:00
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
use Illuminate\Support\Facades\Crypt;
|
2026-06-02 22:30:49 +02:00
|
|
|
use Illuminate\Support\Facades\Storage;
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
class EmailSettingsController extends Controller
|
|
|
|
|
{
|
|
|
|
|
public function index()
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
$settings = EmailSetting::first() ?? new EmailSetting();
|
2026-05-27 07:29:29 +02:00
|
|
|
$senderAccounts = SenderAccount::orderBy('email_address')->get();
|
2026-06-17 13:50:41 +02:00
|
|
|
$googleStatus = app(GoogleOAuthService::class)->getConnectionStatus();
|
|
|
|
|
return view('admin.email-settings.index', compact('settings', 'senderAccounts', 'googleStatus'));
|
2026-05-26 08:14:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function save(Request $request)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
$validated = $request->validate([
|
|
|
|
|
'imap_host' => 'required|string|max:255',
|
|
|
|
|
'imap_port' => 'required|integer|min:1|max:65535',
|
|
|
|
|
'imap_encryption' => 'nullable|in:ssl,tls,none',
|
|
|
|
|
'imap_username' => 'required|string|max:255',
|
|
|
|
|
'imap_password' => 'nullable|string',
|
|
|
|
|
'smtp_host' => 'nullable|string|max:255',
|
|
|
|
|
'smtp_port' => 'nullable|integer|min:1|max:65535',
|
|
|
|
|
'smtp_encryption' => 'nullable|in:ssl,tls,none',
|
2026-06-08 12:09:45 +02:00
|
|
|
'smtp_username' => 'nullable|string|max:255',
|
|
|
|
|
'smtp_password' => 'nullable|string',
|
2026-05-26 08:14:29 +02:00
|
|
|
'email_address' => 'required|email',
|
|
|
|
|
'email_name' => 'nullable|string|max:255',
|
|
|
|
|
'reply_to' => 'nullable|email',
|
|
|
|
|
'sync_interval_minutes' => 'nullable|integer|min:1|max:60',
|
|
|
|
|
'is_active' => 'boolean',
|
2026-06-08 12:09:45 +02:00
|
|
|
'signature' => 'nullable|string',
|
|
|
|
|
'signature_enabled' => 'boolean',
|
2026-06-17 13:50:41 +02:00
|
|
|
'auth_method' => 'nullable|in:password,oauth',
|
|
|
|
|
'google_oauth_connection_id' => 'nullable|integer|exists:google_oauth_connections,id',
|
2026-05-26 08:14:29 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
if (!empty($validated['imap_password'])) {
|
|
|
|
|
$validated['imap_password'] = Crypt::encryptString($validated['imap_password']);
|
|
|
|
|
} else {
|
|
|
|
|
unset($validated['imap_password']);
|
|
|
|
|
}
|
|
|
|
|
if (!empty($validated['smtp_password'])) {
|
|
|
|
|
$validated['smtp_password'] = Crypt::encryptString($validated['smtp_password']);
|
|
|
|
|
} else {
|
|
|
|
|
unset($validated['smtp_password']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$saved = EmailSetting::updateOrCreate(
|
|
|
|
|
['id' => $request->id ?? 1],
|
|
|
|
|
$validated
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$verify = EmailSetting::find($saved->id);
|
2026-06-08 12:09:45 +02:00
|
|
|
|
2026-06-17 13:50:41 +02:00
|
|
|
$allGood = $verify &&
|
|
|
|
|
$verify->imap_host === $validated['imap_host'] &&
|
|
|
|
|
$verify->email_address === $validated['email_address'];
|
2026-06-08 12:09:45 +02:00
|
|
|
|
2026-06-17 13:50:41 +02:00
|
|
|
$allGood = $allGood &&
|
|
|
|
|
(!array_key_exists('signature', $validated) || $verify->signature === $validated['signature']) &&
|
|
|
|
|
(!array_key_exists('signature_enabled', $validated) || (bool)$verify->signature_enabled === (bool)$validated['signature_enabled']);
|
2026-06-08 12:09:45 +02:00
|
|
|
|
2026-06-17 13:50:41 +02:00
|
|
|
if ($allGood) {
|
2026-05-26 08:14:29 +02:00
|
|
|
return back()->with('success', 'Impostazioni email salvate e verificate nel database.');
|
|
|
|
|
} else {
|
|
|
|
|
return back()->with('error', 'Errore nel salvataggio: i dati non sono stati salvati correttamente.');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testConnection(Request $request)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
$settings = EmailSetting::first();
|
|
|
|
|
|
|
|
|
|
if (!$settings) {
|
|
|
|
|
return response()->json(['success' => false, 'message' => 'Configurazione non trovata.']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (empty($settings->imap_host) || empty($settings->email_address)) {
|
|
|
|
|
return response()->json(['success' => false, 'message' => 'Prima salva le impostazioni.']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$result = $settings->testConnection();
|
|
|
|
|
return response()->json($result);
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
$msg = $e->getMessage();
|
|
|
|
|
if (strpos($msg, 'Undefined property') !== false) {
|
|
|
|
|
$msg = 'Impossibile connettersi al server IMAP. Verifica host, porta, encryption e credenziali.';
|
|
|
|
|
}
|
|
|
|
|
return response()->json(['success' => false, 'message' => 'Errore: ' . $msg]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testSmtp(Request $request)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
$request->validate([
|
|
|
|
|
'email' => 'required|email',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$settings = EmailSetting::first();
|
|
|
|
|
|
|
|
|
|
if (!$settings) {
|
|
|
|
|
return response()->json(['success' => false, 'message' => 'Configurazione non trovata.']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
2026-06-17 13:50:41 +02:00
|
|
|
$mailer = $settings->getSmtpMailer();
|
2026-05-26 08:14:29 +02:00
|
|
|
|
2026-06-17 13:50:41 +02:00
|
|
|
if ($mailer === null) {
|
|
|
|
|
return response()->json(['success' => false, 'message' => 'Impossibile creare il mailer SMTP. Verifica la configurazione.']);
|
|
|
|
|
}
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$fromName = $settings->email_name ?? '';
|
|
|
|
|
if (filter_var($fromName, FILTER_VALIDATE_EMAIL)) {
|
|
|
|
|
$fromName = 'Glastree';
|
|
|
|
|
} else {
|
|
|
|
|
$fromName = preg_replace('/[^\p{L}\p{N}\s]/u', '', $fromName);
|
|
|
|
|
$fromName = trim($fromName);
|
|
|
|
|
if (empty($fromName) || strlen($fromName) > 50) {
|
|
|
|
|
$fromName = 'Glastree';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$fromAddress = \Symfony\Component\Mime\Address::create($settings->email_address, $fromName);
|
|
|
|
|
|
|
|
|
|
$email = (new \Symfony\Component\Mime\Email())
|
|
|
|
|
->from($fromAddress)
|
|
|
|
|
->to($request->email)
|
|
|
|
|
->subject('Test Configurazione SMTP - Glastree')
|
|
|
|
|
->text('Test email da Glastree - Configurazione SMTP funziona!');
|
2026-06-17 13:50:41 +02:00
|
|
|
|
2026-05-26 08:14:29 +02:00
|
|
|
$mailer->send($email);
|
|
|
|
|
|
|
|
|
|
\Illuminate\Support\Facades\Log::info('Test SMTP ok', ['to' => $request->email, 'from' => $settings->email_address]);
|
|
|
|
|
|
|
|
|
|
return response()->json(['success' => true, 'message' => 'Email di test inviata a ' . $request->email]);
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
\Illuminate\Support\Facades\Log::error('Test SMTP failed', ['error' => $e->getMessage()]);
|
|
|
|
|
return response()->json(['success' => false, 'message' => 'Errore invio: ' . $e->getMessage()]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function syncNow()
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
$settings = EmailSetting::getActive();
|
|
|
|
|
|
|
|
|
|
if (!$settings) {
|
|
|
|
|
return back()->with('error', 'Nessuna configurazione email attiva.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
app(\App\Http\Controllers\EmailController::class)->syncEmails();
|
|
|
|
|
$settings->update(['last_sync_at' => now()]);
|
|
|
|
|
return back()->with('success', 'Sincronizzazione completata.');
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
return back()->with('error', 'Errore sync: ' . $e->getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-05-27 07:29:29 +02:00
|
|
|
|
|
|
|
|
public function senderStore(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$this->authorizeWrite('settings');
|
|
|
|
|
$data = $request->validate([
|
|
|
|
|
'email_address' => 'required|email|max:255|unique:sender_accounts,email_address',
|
|
|
|
|
'email_name' => 'nullable|string|max:255',
|
|
|
|
|
'smtp_host' => 'nullable|string|max:255',
|
|
|
|
|
'smtp_port' => 'nullable|integer|min:1|max:65535',
|
|
|
|
|
'smtp_encryption' => 'nullable|in:tls,ssl,none',
|
|
|
|
|
'smtp_username' => 'nullable|string|max:255',
|
|
|
|
|
'smtp_password' => 'nullable|string',
|
|
|
|
|
'reply_to' => 'nullable|email|max:255',
|
|
|
|
|
'verify_email' => 'nullable|email|max:255',
|
|
|
|
|
'note' => 'nullable|string|max:500',
|
|
|
|
|
'is_active' => 'boolean',
|
2026-06-17 13:50:41 +02:00
|
|
|
'auth_method' => 'nullable|in:password,oauth',
|
|
|
|
|
'google_oauth_connection_id' => 'nullable|integer|exists:google_oauth_connections,id',
|
2026-05-27 07:29:29 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
if (!empty($data['smtp_password'])) {
|
|
|
|
|
$data['smtp_password'] = Crypt::encryptString($data['smtp_password']);
|
|
|
|
|
} else {
|
|
|
|
|
unset($data['smtp_password']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$sender = SenderAccount::create($data);
|
|
|
|
|
|
|
|
|
|
return back()->with('success', 'Mittente "' . $sender->email_address . '" creato con successo.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function senderUpdate(Request $request, int $id)
|
|
|
|
|
{
|
|
|
|
|
$this->authorizeWrite('settings');
|
|
|
|
|
$sender = SenderAccount::findOrFail($id);
|
|
|
|
|
|
|
|
|
|
$data = $request->validate([
|
|
|
|
|
'email_address' => 'required|email|max:255|unique:sender_accounts,email_address,' . $id,
|
|
|
|
|
'email_name' => 'nullable|string|max:255',
|
|
|
|
|
'smtp_host' => 'nullable|string|max:255',
|
|
|
|
|
'smtp_port' => 'nullable|integer|min:1|max:65535',
|
|
|
|
|
'smtp_encryption' => 'nullable|in:tls,ssl,none',
|
|
|
|
|
'smtp_username' => 'nullable|string|max:255',
|
|
|
|
|
'smtp_password' => 'nullable|string',
|
|
|
|
|
'reply_to' => 'nullable|email|max:255',
|
|
|
|
|
'verify_email' => 'nullable|email|max:255',
|
|
|
|
|
'note' => 'nullable|string|max:500',
|
|
|
|
|
'is_active' => 'boolean',
|
2026-06-17 13:50:41 +02:00
|
|
|
'auth_method' => 'nullable|in:password,oauth',
|
|
|
|
|
'google_oauth_connection_id' => 'nullable|integer|exists:google_oauth_connections,id',
|
2026-05-27 07:29:29 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
if (!empty($data['smtp_password'])) {
|
|
|
|
|
$data['smtp_password'] = Crypt::encryptString($data['smtp_password']);
|
|
|
|
|
} else {
|
|
|
|
|
unset($data['smtp_password']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$sender->update($data);
|
|
|
|
|
|
|
|
|
|
return back()->with('success', 'Mittente "' . $sender->email_address . '" aggiornato.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function senderDestroy(int $id)
|
|
|
|
|
{
|
|
|
|
|
$this->authorizeDelete('settings');
|
|
|
|
|
$sender = SenderAccount::findOrFail($id);
|
|
|
|
|
$sender->delete();
|
|
|
|
|
|
2026-05-27 08:37:37 +02:00
|
|
|
if (request()->expectsJson()) {
|
|
|
|
|
return response()->json(['success' => true, 'message' => 'Mittente eliminato.']);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-27 07:29:29 +02:00
|
|
|
return back()->with('success', 'Mittente eliminato.');
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-02 22:07:16 +02:00
|
|
|
public function destroy(): RedirectResponse
|
|
|
|
|
{
|
|
|
|
|
$this->authorizeDelete('settings');
|
|
|
|
|
|
2026-06-02 22:30:49 +02:00
|
|
|
EmailAttachment::chunk(100, function ($attachments) {
|
|
|
|
|
foreach ($attachments as $attachment) {
|
|
|
|
|
if ($attachment->file_path && Storage::exists($attachment->file_path)) {
|
|
|
|
|
Storage::delete($attachment->file_path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
EmailFolder::whereIn('type', ['inbox', 'sent', 'drafts', 'trash', 'archive', 'starred'])->each(function ($folder) {
|
|
|
|
|
$folder->delete();
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-02 22:07:16 +02:00
|
|
|
$settings = EmailSetting::first();
|
|
|
|
|
if ($settings) {
|
|
|
|
|
$settings->delete();
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-02 22:30:49 +02:00
|
|
|
return redirect('/impostazioni/email')->with('success', 'Configurazione email eliminata. Messaggi, cartelle e allegati rimossi completamente.');
|
2026-06-02 22:07:16 +02:00
|
|
|
}
|
|
|
|
|
|
2026-05-27 07:29:29 +02:00
|
|
|
public function senderTestSmtp(Request $request, int $id)
|
|
|
|
|
{
|
|
|
|
|
$this->authorizeWrite('settings');
|
|
|
|
|
$request->validate(['email' => 'required|email']);
|
|
|
|
|
|
|
|
|
|
$sender = SenderAccount::findOrFail($id);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$sender->sendEmail(
|
|
|
|
|
$request->email,
|
|
|
|
|
'Test Configurazione SMTP - ' . config('app.name'),
|
|
|
|
|
'Test email da ' . config('app.name') . ' - Configurazione SMTP mittente "' . $sender->email_address . '" funziona!'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return response()->json(['success' => true, 'message' => 'Email di test inviata a ' . $request->email]);
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
return response()->json(['success' => false, 'message' => 'Errore invio: ' . $e->getMessage()]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-06-17 13:50:41 +02:00
|
|
|
}
|