|
|
@@ -4,6 +4,8 @@ namespace App\Http\Livewire;
|
|
|
|
|
|
use Illuminate\Support\Facades\Log;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
+use Illuminate\Support\Facades\Hash;
|
|
|
+use Illuminate\Support\Facades\Mail;
|
|
|
use Livewire\Component;
|
|
|
use App\Http\Middleware\TenantMiddleware;
|
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
@@ -16,7 +18,7 @@ class User extends Component
|
|
|
$this->logCurrentDatabase('After tenant connection setup in boot()');
|
|
|
}
|
|
|
|
|
|
- public $records, $name, $cognome, $email, $password, $oldPassword, $level, $enabled, $dataId, $update = false, $add = false;
|
|
|
+ public $records, $name, $cognome, $email, $password, $oldPassword, $level, $enabled, $dataId, $update = false, $add = false, $oldEmail = null;
|
|
|
public $userExists = false;
|
|
|
|
|
|
protected $rules = [
|
|
|
@@ -59,6 +61,240 @@ class User extends Component
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 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 (\Swift_TransportException $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 resetFields()
|
|
|
{
|
|
|
$this->name = '';
|
|
|
@@ -127,18 +363,22 @@ class User extends Component
|
|
|
$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' => bcrypt($this->password),
|
|
|
+ 'password' => $hashedPassword,
|
|
|
'level' => $this->level,
|
|
|
'enabled' => $this->enabled
|
|
|
]);
|
|
|
|
|
|
- $this->logCurrentDatabase('After creating user in store()');
|
|
|
+ $this->logCurrentDatabase('After creating user in tenant database');
|
|
|
|
|
|
- Log::info('User created successfully', [
|
|
|
+ Log::info('User created successfully in tenant database', [
|
|
|
'user_id' => $user->id,
|
|
|
'name' => $this->name,
|
|
|
'cognome' => $this->cognome,
|
|
|
@@ -148,7 +388,32 @@ class User extends Component
|
|
|
'database' => DB::connection()->getDatabaseName()
|
|
|
]);
|
|
|
|
|
|
- session()->flash('success', 'Utente creato');
|
|
|
+ $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) {
|
|
|
+ session()->flash('success', 'Utente creato e email di benvenuto inviata');
|
|
|
+ } else {
|
|
|
+ session()->flash('success', 'Utente creato ma errore nell\'invio email');
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ session()->flash('success', 'Utente creato nel database tenant ma errore nella sincronizzazione master');
|
|
|
+ }
|
|
|
+
|
|
|
$this->resetFields();
|
|
|
$this->add = false;
|
|
|
} catch (\Exception $ex) {
|
|
|
@@ -191,6 +456,7 @@ class User extends Component
|
|
|
$this->add = false;
|
|
|
$this->enabled = $user->enabled;
|
|
|
$this->userExists = true;
|
|
|
+ $this->oldEmail = $user->email;
|
|
|
}
|
|
|
|
|
|
Log::info('User edit loaded', [
|
|
|
@@ -218,30 +484,65 @@ class User extends Component
|
|
|
{
|
|
|
$this->logCurrentDatabase('Start of update() method');
|
|
|
|
|
|
- $this->validate();
|
|
|
+ $rules = [
|
|
|
+ 'name' => 'required',
|
|
|
+ 'cognome' => 'required',
|
|
|
+ 'email' => 'required|email',
|
|
|
+ 'password' => 'nullable|min:6'
|
|
|
+ ];
|
|
|
+
|
|
|
+ $this->validate($rules, $this->messages);
|
|
|
|
|
|
try {
|
|
|
- \App\Models\User::whereId($this->dataId)->update([
|
|
|
+ $currentUser = \App\Models\User::findOrFail($this->dataId);
|
|
|
+ $oldEmail = $currentUser->email;
|
|
|
+ $oldName = $currentUser->name;
|
|
|
+
|
|
|
+ $updateData = [
|
|
|
'name' => $this->name,
|
|
|
'cognome' => $this->cognome,
|
|
|
'email' => $this->email,
|
|
|
- 'password' => bcrypt($this->password),
|
|
|
'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', [
|
|
|
+ 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;
|
|
|
@@ -274,15 +575,23 @@ class User extends Component
|
|
|
$this->logCurrentDatabase('Start of delete() method');
|
|
|
|
|
|
try {
|
|
|
- \App\Models\User::find($id)->delete();
|
|
|
+ $user = \App\Models\User::find($id);
|
|
|
+ $userEmail = $user ? $user->email : null;
|
|
|
+
|
|
|
+ $user->delete();
|
|
|
|
|
|
$this->logCurrentDatabase('After deleting user');
|
|
|
|
|
|
- Log::info('User deleted successfully', [
|
|
|
+ Log::info('User deleted successfully from tenant database', [
|
|
|
'user_id' => $id,
|
|
|
+ 'user_email' => $userEmail,
|
|
|
'database' => DB::connection()->getDatabaseName()
|
|
|
]);
|
|
|
|
|
|
+ if ($userEmail) {
|
|
|
+ $this->deleteUserFromMasterDatabase($userEmail);
|
|
|
+ }
|
|
|
+
|
|
|
session()->flash('success', "Dato eliminato");
|
|
|
} catch (\Exception $e) {
|
|
|
$this->logCurrentDatabase('Error in delete() method');
|