pre version 2
This commit is contained in:
@@ -2,11 +2,13 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Enums\GoogleService;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\EmailAttachment;
|
||||
use App\Models\EmailFolder;
|
||||
use App\Models\EmailSetting;
|
||||
use App\Models\SenderAccount;
|
||||
use App\Services\GoogleOAuthService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
@@ -19,7 +21,8 @@ class EmailSettingsController extends Controller
|
||||
$this->authorizeWrite('settings');
|
||||
$settings = EmailSetting::first() ?? new EmailSetting();
|
||||
$senderAccounts = SenderAccount::orderBy('email_address')->get();
|
||||
return view('admin.email-settings.index', compact('settings', 'senderAccounts'));
|
||||
$googleStatus = app(GoogleOAuthService::class)->getConnectionStatus();
|
||||
return view('admin.email-settings.index', compact('settings', 'senderAccounts', 'googleStatus'));
|
||||
}
|
||||
|
||||
public function save(Request $request)
|
||||
@@ -43,6 +46,8 @@ class EmailSettingsController extends Controller
|
||||
'is_active' => 'boolean',
|
||||
'signature' => 'nullable|string',
|
||||
'signature_enabled' => 'boolean',
|
||||
'auth_method' => 'nullable|in:password,oauth',
|
||||
'google_oauth_connection_id' => 'nullable|integer|exists:google_oauth_connections,id',
|
||||
]);
|
||||
|
||||
if (!empty($validated['imap_password'])) {
|
||||
@@ -61,29 +66,17 @@ class EmailSettingsController extends Controller
|
||||
$validated
|
||||
);
|
||||
|
||||
// Verifica che i dati siano stati salvati
|
||||
$verify = EmailSetting::find($saved->id);
|
||||
if ($verify &&
|
||||
|
||||
$allGood = $verify &&
|
||||
$verify->imap_host === $validated['imap_host'] &&
|
||||
$verify->email_address === $validated['email_address']) {
|
||||
$verify->email_address === $validated['email_address'];
|
||||
|
||||
$signatureMatch = !array_key_exists('signature', $validated) || $verify->signature === $validated['signature'];
|
||||
$signatureEnabledMatch = !array_key_exists('signature_enabled', $validated) || (bool)$verify->signature_enabled === (bool)$validated['signature_enabled'];
|
||||
|
||||
if (!$signatureMatch) {
|
||||
\Illuminate\Support\Facades\Log::warning('Signature mismatch after save', [
|
||||
'expected' => $validated['signature'] ?? null,
|
||||
'actual' => $verify->signature,
|
||||
]);
|
||||
}
|
||||
|
||||
if (!$signatureEnabledMatch) {
|
||||
\Illuminate\Support\Facades\Log::warning('Signature enabled mismatch after save', [
|
||||
'expected' => $validated['signature_enabled'] ?? null,
|
||||
'actual' => $verify->signature_enabled,
|
||||
]);
|
||||
}
|
||||
$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']);
|
||||
|
||||
if ($allGood) {
|
||||
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.');
|
||||
@@ -99,7 +92,6 @@ class EmailSettingsController extends Controller
|
||||
return response()->json(['success' => false, 'message' => 'Configurazione non trovata.']);
|
||||
}
|
||||
|
||||
// Verifica che i dati siano salvati
|
||||
if (empty($settings->imap_host) || empty($settings->email_address)) {
|
||||
return response()->json(['success' => false, 'message' => 'Prima salva le impostazioni.']);
|
||||
}
|
||||
@@ -129,41 +121,13 @@ class EmailSettingsController extends Controller
|
||||
return response()->json(['success' => false, 'message' => 'Configurazione non trovata.']);
|
||||
}
|
||||
|
||||
if (empty($settings->smtp_host)) {
|
||||
$settings->smtp_host = 'smtp.gmail.com';
|
||||
$settings->smtp_port = 587;
|
||||
$settings->smtp_encryption = 'tls';
|
||||
}
|
||||
|
||||
try {
|
||||
$smtpUsername = $settings->smtp_username;
|
||||
$smtpPassword = $settings->smtp_password;
|
||||
|
||||
if (empty($smtpUsername)) {
|
||||
$smtpUsername = $settings->email_address;
|
||||
}
|
||||
if (empty($smtpPassword)) {
|
||||
$smtpPassword = $settings->getDecryptedPassword();
|
||||
} else {
|
||||
$smtpPassword = Crypt::decryptString($smtpPassword);
|
||||
$mailer = $settings->getSmtpMailer();
|
||||
|
||||
if ($mailer === null) {
|
||||
return response()->json(['success' => false, 'message' => 'Impossibile creare il mailer SMTP. Verifica la configurazione.']);
|
||||
}
|
||||
|
||||
$encryption = $settings->smtp_encryption ?? 'tls';
|
||||
$scheme = ($encryption === 'ssl') ? 'smtps' : 'smtp';
|
||||
|
||||
$dsn = sprintf(
|
||||
'%s://%s:%s@%s:%d?encryption=%s',
|
||||
$scheme,
|
||||
rawurlencode($smtpUsername),
|
||||
rawurlencode($smtpPassword),
|
||||
$settings->smtp_host,
|
||||
$settings->smtp_port ?? 587,
|
||||
$encryption
|
||||
);
|
||||
|
||||
$transport = \Symfony\Component\Mailer\Transport::fromDsn($dsn);
|
||||
$mailer = new \Symfony\Component\Mailer\Mailer($transport);
|
||||
|
||||
$fromName = $settings->email_name ?? '';
|
||||
if (filter_var($fromName, FILTER_VALIDATE_EMAIL)) {
|
||||
$fromName = 'Glastree';
|
||||
@@ -182,7 +146,7 @@ class EmailSettingsController extends Controller
|
||||
->to($request->email)
|
||||
->subject('Test Configurazione SMTP - Glastree')
|
||||
->text('Test email da Glastree - Configurazione SMTP funziona!');
|
||||
|
||||
|
||||
$mailer->send($email);
|
||||
|
||||
\Illuminate\Support\Facades\Log::info('Test SMTP ok', ['to' => $request->email, 'from' => $settings->email_address]);
|
||||
@@ -227,6 +191,8 @@ class EmailSettingsController extends Controller
|
||||
'verify_email' => 'nullable|email|max:255',
|
||||
'note' => 'nullable|string|max:500',
|
||||
'is_active' => 'boolean',
|
||||
'auth_method' => 'nullable|in:password,oauth',
|
||||
'google_oauth_connection_id' => 'nullable|integer|exists:google_oauth_connections,id',
|
||||
]);
|
||||
|
||||
if (!empty($data['smtp_password'])) {
|
||||
@@ -257,6 +223,8 @@ class EmailSettingsController extends Controller
|
||||
'verify_email' => 'nullable|email|max:255',
|
||||
'note' => 'nullable|string|max:500',
|
||||
'is_active' => 'boolean',
|
||||
'auth_method' => 'nullable|in:password,oauth',
|
||||
'google_oauth_connection_id' => 'nullable|integer|exists:google_oauth_connections,id',
|
||||
]);
|
||||
|
||||
if (!empty($data['smtp_password'])) {
|
||||
@@ -326,4 +294,4 @@ class EmailSettingsController extends Controller
|
||||
return response()->json(['success' => false, 'message' => 'Errore invio: ' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class DocumentoController extends Controller
|
||||
} elseif ($folderId) {
|
||||
$query->where('cartella_id', $folderId);
|
||||
} else {
|
||||
$query->whereNull('repository_id');
|
||||
$query->whereNull('repository_id')->whereNull('cartella_id');
|
||||
}
|
||||
|
||||
$documenti = $query->paginate(20);
|
||||
@@ -204,24 +204,24 @@ class DocumentoController extends Controller
|
||||
$data = $request->validate([
|
||||
'nome_file' => 'required|string|max:255',
|
||||
'tipologia' => 'required|' . $tipologieRule,
|
||||
'visibilita' => 'nullable|string',
|
||||
'contesto_tipo' => 'nullable|in:individuo,gruppo,evento,mailing',
|
||||
'visibilita_target_id' => 'nullable|integer',
|
||||
'visibilita_target_type' => 'nullable|string',
|
||||
'note' => 'nullable|string',
|
||||
'tags' => 'nullable|array',
|
||||
'tags.*' => 'exists:tags,id',
|
||||
]);
|
||||
|
||||
$data['visibilita'] = $request->contesto_tipo ?: 'pubblico';
|
||||
$contestoTipo = $data['contesto_tipo'] ?? null;
|
||||
$data['visibilita'] = $contestoTipo ?: 'pubblico';
|
||||
|
||||
if ($request->contesto_tipo) {
|
||||
if ($contestoTipo) {
|
||||
$typeMap = [
|
||||
'individuo' => Individuo::class,
|
||||
'gruppo' => Gruppo::class,
|
||||
'evento' => Evento::class,
|
||||
'mailing' => \App\Models\MailingList::class,
|
||||
];
|
||||
$data['visibilita_target_type'] = $typeMap[$request->contesto_tipo] ?? null;
|
||||
$data['visibilita_target_type'] = $typeMap[$contestoTipo] ?? null;
|
||||
} else {
|
||||
$data['visibilita'] = 'pubblico';
|
||||
$data['visibilita_target_id'] = null;
|
||||
@@ -236,21 +236,27 @@ class DocumentoController extends Controller
|
||||
$documento->tags()->detach();
|
||||
}
|
||||
|
||||
return redirect('/documenti')->with('success', 'Documento aggiornato.');
|
||||
$redirect = $request->input('folder_id') ? '/documenti?folder_id=' . $request->input('folder_id') : '/documenti';
|
||||
return redirect($redirect)->with('success', 'Documento aggiornato.');
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->authorizeWrite('documenti');
|
||||
$tipologieValidi = TipologiaDocumento::opzioni();
|
||||
$tipologieRule = 'in:' . implode(',', $tipologieValidi);
|
||||
|
||||
$data = $request->validate([
|
||||
'nome_file' => 'required|string|max:255',
|
||||
'tipologia' => 'required|in:avatar,galleria,documento,statuto,altro',
|
||||
'tipologia' => 'required|' . $tipologieRule,
|
||||
'file' => 'required|file|max:10240',
|
||||
'visibilita' => 'required|in:pubblico,individuo,gruppo',
|
||||
'visibilita_target_id' => 'nullable|integer',
|
||||
'visibilita_target_type' => 'nullable|string',
|
||||
'cartella_id' => 'nullable|integer|exists:documenti_cartelle,id',
|
||||
'repository_id' => 'nullable|integer|exists:storage_repositories,id',
|
||||
'tags' => 'nullable|array',
|
||||
'tags.*' => 'exists:tags,id',
|
||||
]);
|
||||
|
||||
$repositoryId = $data['repository_id'] ?? null;
|
||||
@@ -284,7 +290,7 @@ class DocumentoController extends Controller
|
||||
$visibilitaTargetType = Gruppo::class;
|
||||
}
|
||||
|
||||
Documento::create([
|
||||
$doc = Documento::create([
|
||||
'nome_file' => $data['nome_file'],
|
||||
'file_path' => $filePath,
|
||||
'storage_disk' => $disk ?? null,
|
||||
@@ -300,7 +306,13 @@ class DocumentoController extends Controller
|
||||
'repository_id' => $repositoryId,
|
||||
]);
|
||||
|
||||
if ($doc && $request->has('tags')) {
|
||||
$doc->tags()->sync($request->tags);
|
||||
}
|
||||
$redirect = $request->_redirect ?? url()->previous();
|
||||
if ($request->filled('folder_id')) {
|
||||
$redirect = '/documenti?folder_id=' . $request->input('folder_id');
|
||||
}
|
||||
return redirect($redirect)->with('success', 'Documento caricato.');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Evento;
|
||||
@@ -630,4 +632,39 @@ class EventoController extends Controller
|
||||
|
||||
return redirect('/eventi')->with('success', $message);
|
||||
}
|
||||
|
||||
public function massTag(Request $request)
|
||||
{
|
||||
$this->authorizeWrite('eventi');
|
||||
$idsInput = $request->input('ids', '');
|
||||
$ids = is_array($idsInput) ? $idsInput : (is_string($idsInput) ? explode(',', $idsInput) : []);
|
||||
|
||||
if (empty($ids)) {
|
||||
return back()->with('error', 'Nessun evento selezionato.');
|
||||
}
|
||||
|
||||
$data = $request->validate([
|
||||
'tags' => 'required|array',
|
||||
'tags.*' => 'exists:tags,id',
|
||||
'mode' => 'required|in:assign,remove',
|
||||
]);
|
||||
|
||||
$tagIds = $data['tags'];
|
||||
$mode = $data['mode'];
|
||||
$count = 0;
|
||||
|
||||
Evento::whereIn('id', $ids)->chunk(100, function ($eventi) use ($tagIds, $mode, &$count) {
|
||||
foreach ($eventi as $evento) {
|
||||
if ($mode === 'assign') {
|
||||
$evento->tags()->syncWithoutDetaching($tagIds);
|
||||
} else {
|
||||
$evento->tags()->detach($tagIds);
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
});
|
||||
|
||||
$actionLabel = $mode === 'assign' ? 'assegnati' : 'rimossi';
|
||||
return back()->with('success', "Tag $actionLabel per $count eventi.");
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Evento;
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\GoogleService;
|
||||
use App\Models\GoogleOAuthConnection;
|
||||
use App\Services\GoogleOAuthService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class GoogleOAuthController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly GoogleOAuthService $googleOAuthService,
|
||||
) {}
|
||||
|
||||
public function redirect(string $service): RedirectResponse
|
||||
{
|
||||
try {
|
||||
$serviceEnum = GoogleService::from($service);
|
||||
} catch (\ValueError $e) {
|
||||
return redirect()->back()->withErrors(['error' => 'Servizio Google non valido: ' . $service]);
|
||||
}
|
||||
|
||||
$authUrl = $this->googleOAuthService->getAuthUrl($service);
|
||||
|
||||
return redirect()->away($authUrl);
|
||||
}
|
||||
|
||||
public function callback(Request $request): RedirectResponse
|
||||
{
|
||||
$error = $request->input('error');
|
||||
if ($error) {
|
||||
$message = match ($error) {
|
||||
'access_denied' => 'Accesso negato. Autorizzazione non concessa.',
|
||||
default => 'Errore Google: ' . $error,
|
||||
};
|
||||
return redirect()->route('impostazioni.index', ['tab' => 'google'])
|
||||
->withErrors(['error' => $message]);
|
||||
}
|
||||
|
||||
$code = $request->input('code');
|
||||
if (!$code) {
|
||||
return redirect()->route('impostazioni.index', ['tab' => 'google'])
|
||||
->withErrors(['error' => 'Nessun codice di autorizzazione ricevuto']);
|
||||
}
|
||||
|
||||
$state = $request->input('state', 'email');
|
||||
try {
|
||||
$service = GoogleService::from($state);
|
||||
} catch (\ValueError $e) {
|
||||
$service = GoogleService::Email;
|
||||
}
|
||||
|
||||
try {
|
||||
$connection = $this->googleOAuthService->handleCallback($code, $service);
|
||||
|
||||
$message = match ($service) {
|
||||
GoogleService::Email => 'Account email Gmail connesso con successo!',
|
||||
GoogleService::Drive => 'Account Google Drive connesso con successo!',
|
||||
GoogleService::Calendar => 'Account Google Calendar connesso con successo!',
|
||||
};
|
||||
|
||||
return redirect()->route('impostazioni.index', ['tab' => 'google'])
|
||||
->with('success', $message);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Google OAuth callback error', [
|
||||
'error' => $e->getMessage(),
|
||||
'service' => $service->value,
|
||||
]);
|
||||
|
||||
return redirect()->route('impostazioni.index', ['tab' => 'google'])
|
||||
->withErrors(['error' => 'Errore durante la connessione: ' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function revoke(GoogleOAuthConnection $connection): RedirectResponse
|
||||
{
|
||||
if ($connection->user_id !== auth()->id()) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
try {
|
||||
$service = GoogleService::from($connection->service);
|
||||
|
||||
$message = match ($service) {
|
||||
GoogleService::Email => 'Account email Gmail disconnesso.',
|
||||
GoogleService::Drive => 'Account Google Drive disconnesso.',
|
||||
GoogleService::Calendar => 'Account Google Calendar disconnesso.',
|
||||
};
|
||||
|
||||
$this->googleOAuthService->revoke($connection);
|
||||
|
||||
return redirect()->route('impostazioni.index', ['tab' => 'google'])
|
||||
->with('success', $message);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Google OAuth revoke error', [
|
||||
'error' => $e->getMessage(),
|
||||
'connection_id' => $connection->id,
|
||||
]);
|
||||
|
||||
return redirect()->route('impostazioni.index', ['tab' => 'google'])
|
||||
->withErrors(['error' => 'Errore durante la disconnessione: ' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function status(): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$status = $this->googleOAuthService->getConnectionStatus();
|
||||
|
||||
return response()->json($status);
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ use App\Models\Ruolo;
|
||||
use App\Models\SenderAccount;
|
||||
use App\Models\StorageRepository;
|
||||
use App\Models\Tag;
|
||||
use App\Services\GoogleOAuthService;
|
||||
use App\Models\TipologiaDocumento;
|
||||
use App\Models\TipologiaEvento;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@@ -34,8 +35,9 @@ class ImpostazioniController extends Controller
|
||||
$repositories = StorageRepository::orderBy('ordine')->get();
|
||||
$googleDriveNewToken = session('google_drive_new_token');
|
||||
$calendarioConnessioni = CalendarioConnessione::orderBy('ordine')->get();
|
||||
$googleStatus = app(GoogleOAuthService::class)->getConnectionStatus();
|
||||
|
||||
return view('impostazioni.index', compact('tipologie', 'tipologieEventi', 'ruoli', 'tags', 'appSettings', 'emailSettings', 'senderAccounts', 'repositories', 'googleDriveNewToken', 'calendarioConnessioni'));
|
||||
return view('impostazioni.index', compact('tipologie', 'tipologieEventi', 'ruoli', 'tags', 'appSettings', 'emailSettings', 'senderAccounts', 'repositories', 'googleDriveNewToken', 'calendarioConnessioni', 'googleStatus'));
|
||||
}
|
||||
|
||||
public function saveAppSettings(Request $request)
|
||||
|
||||
Reference in New Issue
Block a user