setupTenantConnection(); $this->logCurrentDatabase('After tenant connection setup in boot()'); } public $records, $name, $cognome, $email, $password, $oldPassword, $level, $enabled, $dataId, $update = false, $add = false, $oldEmail = null; public $userExists = false; public $password_confirmation; protected $rules = [ 'name' => 'required', 'cognome' => 'required', 'email' => 'required', 'password' => 'required', 'password_confirmation' => 'required|same:password' ]; protected $messages = [ 'name.required' => 'Il nome è obbligatorio', 'cognome.required' => 'Il cognome è obbligatorio', 'email.required' => 'La mail è obbligatoria', 'password.required' => 'La password è obbligatoria', 'password_confirmation.required' => 'Ripeti la password inserita', 'password_confirmation.same' => 'Le password non coincidono', ]; /** * Helper method to log current database information */ private function logCurrentDatabase($context = '') { try { $currentConnection = DB::getDefaultConnection(); $currentDatabase = DB::connection()->getDatabaseName(); $user = Auth::user(); Log::info('Database Connection Info', [ 'context' => $context, 'current_connection' => $currentConnection, 'current_database' => $currentDatabase, 'user_id' => $user ? $user->id : null, 'user_tenant_database' => $user ? $user->tenant_database : null, 'user_tenant_username' => $user ? $user->tenant_username : null, ]); } catch (\Exception $e) { Log::error('Failed to get database info', [ 'context' => $context, 'error' => $e->getMessage() ]); } } /** * Create or update user in master database */ private function syncUserToMasterDatabase($userData, $action = 'create', $oldEmail = null) { try { Log::info('Syncing user to master database', [ 'action' => $action, 'email' => $userData['email'], 'old_email' => $oldEmail ]); $masterConfig = [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE'), 'username' => env('DB_USERNAME'), 'password' => env('DB_PASSWORD'), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ]; config(['database.connections.master_sync' => $masterConfig]); $currentUser = Auth::user(); $masterData = [ 'name' => $userData['name'], 'email' => $userData['email'], 'password' => $userData['password'], 'tenant_database' => $currentUser->tenant_database, 'tenant_username' => $currentUser->tenant_username, 'tenant_password' => $currentUser->tenant_password, 'tenant_host' => '127.0.0.1', 'created_at' => now(), 'updated_at' => now() ]; if ($action === 'create') { $inserted = DB::connection('master_sync') ->table('users') ->insert($masterData); if ($inserted) { Log::info('Successfully created user in master database', [ 'email' => $userData['email'], 'tenant_database' => $currentUser->tenant_database ]); return true; } else { Log::warning('Failed to create user in master database', [ 'email' => $userData['email'] ]); return false; } } elseif ($action === 'update') { $searchEmail = $oldEmail ?: $userData['email']; unset($masterData['created_at']); $updated = DB::connection('master_sync') ->table('users') ->where('email', $searchEmail) ->update($masterData); if ($updated) { Log::info('Successfully updated user in master database', [ 'old_email' => $searchEmail, 'new_email' => $userData['email'] ]); return true; } else { Log::warning('No user found in master database to update', [ 'search_email' => $searchEmail ]); return false; } } } catch (\Exception $e) { Log::error('Failed to sync user to master database', [ 'action' => $action, 'email' => $userData['email'], 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return false; } finally { // Clean up the temporary connection try { DB::purge('master_sync'); } catch (\Exception $e) { // Ignore cleanup errors } } } /** * Delete user from master database */ private function deleteUserFromMasterDatabase($email) { try { Log::info('Deleting user from master database', [ 'email' => $email ]); $masterConfig = [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE'), 'username' => env('DB_USERNAME'), 'password' => env('DB_PASSWORD'), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ]; config(['database.connections.master_delete' => $masterConfig]); $deleted = DB::connection('master_delete') ->table('users') ->where('email', $email) ->delete(); if ($deleted) { Log::info('Successfully deleted user from master database', [ 'email' => $email, 'rows_affected' => $deleted ]); return true; } else { Log::warning('No user found in master database to delete', [ 'email' => $email ]); return false; } } catch (\Exception $e) { Log::error('Failed to delete user from master database', [ 'email' => $email, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return false; } finally { try { DB::purge('master_delete'); } catch (\Exception $e) { } } } /** * Send welcome email to new user */ private function sendWelcomeEmail($userData, $plainPassword) { try { $currentUser = Auth::user(); $companyName = 'Leezard'; Log::info('Preparing to send welcome email', [ 'recipient' => $userData['email'], 'company' => $companyName, 'mail_from' => config('mail.from.address'), 'mail_host' => config('mail.mailers.smtp.host'), 'mail_port' => config('mail.mailers.smtp.port') ]); $emailData = [ 'name' => $userData['name'], 'cognome' => $userData['cognome'], 'email' => $userData['email'], 'password' => $plainPassword, 'level' => $userData['level'], 'company' => $companyName, 'login_url' => url('/'), 'created_by' => $currentUser->name ]; try { $viewContent = view('emails.welcome-user', $emailData)->render(); Log::info('Email template rendered successfully', ['template_length' => strlen($viewContent)]); } catch (\Exception $viewException) { Log::error('Email template rendering failed', ['error' => $viewException->getMessage()]); throw new \Exception('Email template error: ' . $viewException->getMessage()); } Mail::send('emails.welcome-user', $emailData, function ($message) use ($userData, $companyName) { $message->to($userData['email'], $userData['name'] . ' ' . $userData['cognome']) ->subject('Benvenuto su Leezard - Account Creato') ->from(config('mail.from.address'), config('mail.from.name')); if (env('MAIL_CCN')) { $message->bcc(env('MAIL_CCN')); } }); Log::info('Welcome email sent successfully', [ 'recipient' => $userData['email'], 'company' => $companyName, 'subject' => 'Benvenuto in ' . $companyName . ' - Account Creato' ]); return true; } catch (\Exception $e) { Log::error('SMTP Transport error when sending welcome email', [ 'recipient' => $userData['email'], 'error' => $e->getMessage(), 'mail_config' => [ 'host' => config('mail.mailers.smtp.host'), 'port' => config('mail.mailers.smtp.port'), 'encryption' => config('mail.mailers.smtp.encryption'), 'username' => config('mail.mailers.smtp.username') ] ]); return false; } catch (\Exception $e) { Log::error('General error when sending welcome email', [ 'recipient' => $userData['email'], 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return false; } } public function sendSimpleWelcomeEmail($email, $userData) { try { $subject = "Benvenuto su " . $userData['company'] . " – Account Creato"; $message = "Ciao " . $userData['name'] . " " . $userData['cognome'] . ",\n\n"; $message .= "Il tuo account è stato creato con successo su " . $userData['company'] . ".\n\n"; $message .= "Le tue credenziali di accesso:\n"; $message .= "Email: " . $userData['email'] . "\n"; $message .= "Password: " . $userData['password'] . "\n\n"; $message .= "Per motivi di sicurezza, dovrai cambiare la password al primo accesso.\n\n"; $message .= "Accedi ora: " . $userData['login_url'] . "\n\n"; $message .= "Grazie e benvenuto!\n"; $message .= "Il team di " . $userData['company']; // Send simple text email mail($email, $subject, $message, [ 'From' => config('mail.from.address'), 'Reply-To' => config('mail.from.address'), 'Content-Type' => 'text/plain; charset=UTF-8' ]); return true; } catch (\Exception $e) { Log::error('Simple email sending failed', [ 'email' => $email, 'error' => $e->getMessage() ]); return false; } } public function resetFields() { $this->name = ''; $this->cognome = ''; $this->email = ''; $this->password = ''; $this->password_confirmation = ''; $this->oldPassword = ''; $this->level = 0; $this->enabled = true; $this->emit('load-data-table'); } public function render() { $this->logCurrentDatabase('Before fetching users in render()'); $this->records = \App\Models\User::select('id', 'name', 'cognome', 'email', 'password', 'level', 'enabled')->get(); $this->logCurrentDatabase('After fetching users in render()'); return view('livewire.user'); } public function add() { if (!$this->canAddUser()) { session()->flash('error', 'Non hai i permessi per aggiungere utenti.'); return; } $this->logCurrentDatabase('In add() method'); $this->resetFields(); $this->add = true; $this->update = false; $this->enabled = true; $this->userExists = false; } public function store() { if (!$this->canAddUser()) { session()->flash('error', 'Non hai i permessi per aggiungere utenti.'); return; } $this->logCurrentDatabase('Start of store() method'); Log::info('User store', [ 'name' => $this->name, 'cognome' => $this->cognome, 'email' => $this->email, 'level' => $this->level, 'enabled' => $this->enabled ]); $rules = [ 'name' => 'required', 'cognome' => 'required', 'email' => 'required|email|unique:users,email', 'password' => 'required|min:6', 'password_confirmation' => 'required|same:password' ]; $messages = [ 'name.required' => 'Il nome è obbligatorio', 'cognome.required' => 'Il cognome è obbligatorio', 'email.required' => 'La mail è obbligatoria', 'email.email' => 'La mail deve essere un indirizzo valido', 'email.unique' => 'Questa mail è già stata utilizzata', 'password.required' => 'La password è obbligatoria', 'password.min' => 'La password deve essere di almeno 6 caratteri', 'password_confirmation.required' => 'Ripeti la password inserita', 'password_confirmation.same' => 'Le password non coincidono', ]; $this->validate($rules, $messages); $this->logCurrentDatabase('Before creating user in store()'); try { $plainPassword = $this->password; $hashedPassword = bcrypt($this->password); $user = \App\Models\User::create([ 'name' => $this->name, 'cognome' => $this->cognome, 'email' => $this->email, 'password' => $hashedPassword, 'level' => $this->level, 'enabled' => $this->enabled ]); $this->logCurrentDatabase('After creating user in tenant database'); Log::info('User created successfully in tenant database', [ 'user_id' => $user->id, 'name' => $this->name, 'cognome' => $this->cognome, 'email' => $this->email, 'level' => $this->level, 'enabled' => $this->enabled, 'database' => DB::connection()->getDatabaseName() ]); $masterSyncSuccess = $this->syncUserToMasterDatabase([ 'name' => $this->name, 'cognome' => $this->cognome, 'email' => $this->email, 'password' => $hashedPassword, 'level' => $this->level, 'enabled' => $this->enabled ], 'create'); if ($masterSyncSuccess) { $emailSent = $this->sendWelcomeEmail([ 'name' => $this->name, 'cognome' => $this->cognome, 'email' => $this->email, 'level' => $this->level ], $plainPassword); if (!$emailSent) { Log::info('HTML email failed, trying simple email', ['email' => $this->email]); $emailSent = $this->sendSimpleWelcomeEmail($this->email, [ 'name' => $this->name, 'cognome' => $this->cognome, 'email' => $this->email, 'password' => $plainPassword, 'level' => $this->level, 'company' => 'Leezard', 'login_url' => url('/') ]); } if ($emailSent) { session()->flash('success', 'Utente creato e email di benvenuto inviata con successo'); } else { session()->flash('success', 'Utente creato ma errore nell\'invio dell\'email. Controlla i log per dettagli.'); } } else { session()->flash('success', 'Utente creato nel database tenant ma errore nella sincronizzazione master'); } $this->resetFields(); $this->add = false; } catch (\Exception $ex) { $this->logCurrentDatabase('Error in store() method'); Log::error('User creation failed', [ 'error' => $ex->getMessage(), 'database' => DB::connection()->getDatabaseName(), 'user_data' => [ 'name' => $this->name, 'cognome' => $this->cognome, 'email' => $this->email, 'level' => $this->level, 'enabled' => $this->enabled ] ]); session()->flash('error', 'Errore (' . $ex->getMessage() . ')'); } } public function edit($id) { if (!$this->canEditUser($id)) { session()->flash('error', 'Non hai i permessi per modificare questo utente.'); return; } $this->logCurrentDatabase('Start of edit() method'); try { $user = \App\Models\User::findOrFail($id); $this->logCurrentDatabase('After finding user in edit()'); if (!$user) { session()->flash('error', 'Utente non trovato'); } else { $this->name = $user->name; $this->cognome = $user->cognome; $this->email = $user->email; $this->level = $user->level; $this->dataId = $user->id; $this->update = true; $this->add = false; $this->enabled = $user->enabled; $this->userExists = true; // Store old email for master database update $this->oldEmail = $user->email; } Log::info('User edit loaded', [ 'user_id' => $id, 'name' => $this->name, 'cognome' => $this->cognome, 'email' => $this->email, 'level' => $this->level, 'database' => DB::connection()->getDatabaseName() ]); } catch (\Exception $ex) { $this->logCurrentDatabase('Error in edit() method'); Log::error('User edit failed', [ 'user_id' => $id, 'error' => $ex->getMessage(), 'database' => DB::connection()->getDatabaseName() ]); session()->flash('error', 'Errore (' . $ex->getMessage() . ')'); } } public function update() { $this->logCurrentDatabase('Start of update() method'); $rules = [ 'name' => 'required', 'cognome' => 'required', 'email' => 'required|email', 'password' => 'nullable|min:6', 'password_confirmation' => 'required|same:password' ]; $this->validate($rules, $this->messages); try { $currentUser = \App\Models\User::findOrFail($this->dataId); $oldEmail = $currentUser->email; $oldName = $currentUser->name; $updateData = [ 'name' => $this->name, 'cognome' => $this->cognome, 'email' => $this->email, 'level' => $this->level, 'enabled' => $this->enabled ]; $passwordChanged = !empty($this->password); if ($passwordChanged) { $hashedPassword = bcrypt($this->password); $updateData['password'] = $hashedPassword; } \App\Models\User::whereId($this->dataId)->update($updateData); $this->logCurrentDatabase('After updating user'); Log::info('User updated successfully in tenant database', [ 'user_id' => $this->dataId, 'name' => $this->name, 'cognome' => $this->cognome, 'email' => $this->email, 'level' => $this->level, 'enabled' => $this->enabled, 'password_changed' => $passwordChanged, 'database' => DB::connection()->getDatabaseName() ]); $emailChanged = $oldEmail !== $this->email; $nameChanged = $oldName !== $this->name; if ($emailChanged || $nameChanged || $passwordChanged) { $masterData = [ 'name' => $this->name, 'email' => $this->email ]; if ($passwordChanged) { $masterData['password'] = $hashedPassword; } $this->syncUserToMasterDatabase($masterData, 'update', $oldEmail); } session()->flash('success', 'Dato aggiornato'); $this->resetFields(); $this->update = false; } catch (\Exception $ex) { $this->logCurrentDatabase('Error in update() method'); Log::error('User update failed', [ 'user_id' => $this->dataId, 'error' => $ex->getMessage(), 'database' => DB::connection()->getDatabaseName() ]); session()->flash('error', 'Errore (' . $ex->getMessage() . ')'); } } public function cancel() { $this->logCurrentDatabase('In cancel() method'); $this->resetFields(); $this->add = false; $this->update = false; $this->userExists = false; $this->enabled = false; } public function delete($id) { Log::info('Delete method called', [ 'user_id_to_delete' => $id, 'current_user_id' => Auth::id(), 'current_user_level' => Auth::user()->level ]); if (!$this->canDeleteUser($id)) { Log::warning('Delete permission denied', [ 'user_id_to_delete' => $id, 'current_user_id' => Auth::id(), 'current_user_level' => Auth::user()->level ]); session()->flash('error', 'Non hai i permessi per eliminare questo utente.'); return; } $this->logCurrentDatabase('Start of delete() method'); try { $user = \App\Models\User::find($id); if (!$user) { Log::error('User not found for deletion', ['user_id' => $id]); session()->flash('error', 'Utente non trovato.'); return; } $userEmail = $user->email; $userName = $user->name; $userCognome = $user->cognome; Log::info('Found user for deletion', [ 'user_id' => $id, 'user_email' => $userEmail, 'user_name' => $userName . ' ' . $userCognome ]); $deleted = $user->delete(); if (!$deleted) { throw new \Exception('Failed to delete user from tenant database'); } $this->logCurrentDatabase('After deleting user from tenant'); Log::info('User deleted successfully from tenant database', [ 'user_id' => $id, 'user_email' => $userEmail, 'database' => DB::connection()->getDatabaseName() ]); $masterDeleted = $this->deleteUserFromMasterDatabase($userEmail); if ($masterDeleted) { Log::info('User deleted from both databases successfully', [ 'user_id' => $id, 'user_email' => $userEmail ]); session()->flash('success', "Utente {$userName} {$userCognome} eliminato con successo"); } else { Log::warning('User deleted from tenant but failed to delete from master', [ 'user_id' => $id, 'user_email' => $userEmail ]); session()->flash('success', "Utente eliminato dal database tenant, ma errore nella sincronizzazione master"); } $this->emit('userDeleted'); $this->emit('load-data-table'); } catch (\Exception $e) { $this->logCurrentDatabase('Error in delete() method'); Log::error('User deletion failed', [ 'user_id' => $id, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), 'database' => DB::connection()->getDatabaseName() ]); session()->flash('error', 'Errore durante l\'eliminazione: ' . $e->getMessage()); } } private function canEditUser($userId) { $currentUser = Auth::user(); if ($currentUser->level == 0) { $targetUser = \App\Models\User::find($userId); return $targetUser && $targetUser->email != 'admin@admin.com'; } return $userId == $currentUser->id; } /** * Check if current user can edit email and password of a specific user */ private function canEditEmailAndPassword($userId) { $currentUser = Auth::user(); return $userId == $currentUser->id; } /** * Check if current user can delete a specific user */ private function canDeleteUser($userId) { $currentUser = Auth::user(); if ($currentUser->level != 0) { return false; } if ($userId == $currentUser->id) { return false; } $targetUser = \App\Models\User::find($userId); if ($targetUser && $targetUser->email == 'admin@admin.com') { return false; } return true; } /** * Check if current user can add users */ private function canAddUser() { $currentUser = Auth::user(); return $currentUser->level == 0; } }