FirstLoginController.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\Request;
  4. use Illuminate\Support\Facades\Auth;
  5. use Illuminate\Support\Facades\Hash;
  6. use Illuminate\Support\Facades\DB;
  7. use Illuminate\Support\Facades\Log;
  8. use Illuminate\Support\Facades\Mail;
  9. use App\Http\Middleware\TenantMiddleware;
  10. class FirstLoginController extends Controller
  11. {
  12. public function __construct()
  13. {
  14. $this->middleware('auth');
  15. app(TenantMiddleware::class)->setupTenantConnection();
  16. }
  17. public function show()
  18. {
  19. $user = Auth::user();
  20. // If already completed first login, redirect to dashboard
  21. if ($user->first_login_completed) {
  22. return redirect('/dashboard');
  23. }
  24. return view('first-login');
  25. }
  26. public function complete(Request $request)
  27. {
  28. // Validate only password
  29. $request->validate([
  30. 'password' => 'required|min:6|confirmed',
  31. ], [
  32. 'password.required' => 'La password è obbligatoria',
  33. 'password.min' => 'La password deve essere di almeno 6 caratteri',
  34. 'password.confirmed' => 'Le password non coincidono',
  35. ]);
  36. $currentUser = Auth::user();
  37. Log::info('Starting first login completion', [
  38. 'user_id' => $currentUser->id,
  39. 'email' => $currentUser->email
  40. ]);
  41. try {
  42. $this->updateTenantDatabase($currentUser, $request->password);
  43. $this->updateMasterDatabaseSafely($currentUser, $request->password);
  44. $this->sendAccountActivationEmailSafely($currentUser);
  45. return redirect('/dashboard')->with('success', 'Password impostata con successo! Benvenuto in Leezard.cloud.');
  46. } catch (\Exception $e) {
  47. Log::error('First login completion failed', [
  48. 'user_id' => $currentUser->id,
  49. 'error' => $e->getMessage(),
  50. 'trace' => $e->getTraceAsString()
  51. ]);
  52. return back()
  53. ->withErrors(['error' => 'Errore durante l\'impostazione della password. Riprova.']);
  54. }
  55. }
  56. private function updateTenantDatabase($currentUser, $password)
  57. {
  58. try {
  59. Log::info('Updating tenant database', ['user_id' => $currentUser->id]);
  60. $user = \App\Models\User::findOrFail($currentUser->id);
  61. $user->password = Hash::make($password);
  62. $user->first_login_completed = true;
  63. $user->email_verified_at = now();
  64. $user->save();
  65. Log::info('Tenant database updated successfully', ['user_id' => $currentUser->id]);
  66. } catch (\Exception $e) {
  67. Log::error('Failed to update tenant database', [
  68. 'user_id' => $currentUser->id,
  69. 'error' => $e->getMessage()
  70. ]);
  71. throw new \Exception('Errore durante l\'aggiornamento del database locale: ' . $e->getMessage());
  72. }
  73. }
  74. private function updateMasterDatabaseSafely($currentUser, $password)
  75. {
  76. try {
  77. Log::info('Attempting to update master database', ['user_id' => $currentUser->id]);
  78. if (!env('DB_DATABASE')) {
  79. Log::warning('No master database configured, skipping master update');
  80. return;
  81. }
  82. $this->updateMasterDatabaseWithTimeout($currentUser, $password);
  83. } catch (\Exception $e) {
  84. Log::error('Master database update failed (non-critical)', [
  85. 'user_id' => $currentUser->id,
  86. 'error' => $e->getMessage()
  87. ]);
  88. }
  89. }
  90. private function updateMasterDatabaseWithTimeout($currentUser, $password)
  91. {
  92. $originalTimeout = ini_get('max_execution_time');
  93. set_time_limit(10);
  94. try {
  95. $masterConfig = [
  96. 'driver' => 'mysql',
  97. 'host' => env('DB_HOST', '127.0.0.1'),
  98. 'port' => env('DB_PORT', '3306'),
  99. 'database' => env('DB_DATABASE'),
  100. 'username' => env('DB_USERNAME'),
  101. 'password' => env('DB_PASSWORD'),
  102. 'charset' => 'utf8mb4',
  103. 'collation' => 'utf8mb4_unicode_ci',
  104. 'prefix' => '',
  105. 'strict' => true,
  106. 'engine' => null,
  107. 'options' => [
  108. \PDO::ATTR_TIMEOUT => 5,
  109. ],
  110. ];
  111. config(['database.connections.master_temp' => $masterConfig]);
  112. $connection = DB::connection('master_temp');
  113. $connection->getPdo();
  114. Log::info('Master database connection established');
  115. $updateData = [
  116. 'password' => Hash::make($password),
  117. 'first_login_completed' => true,
  118. 'email_verified_at' => now(),
  119. 'updated_at' => now()
  120. ];
  121. $updated = $connection->table('users')
  122. ->where('email', $currentUser->email)
  123. ->update($updateData);
  124. if ($updated) {
  125. Log::info('Master database updated successfully', [
  126. 'email' => $currentUser->email,
  127. 'rows_updated' => $updated
  128. ]);
  129. } else {
  130. Log::warning('No rows updated in master database', [
  131. 'email' => $currentUser->email
  132. ]);
  133. }
  134. DB::purge('master_temp');
  135. } catch (\Exception $e) {
  136. Log::error('Master database update timeout or error', [
  137. 'error' => $e->getMessage(),
  138. 'user_email' => $currentUser->email
  139. ]);
  140. try {
  141. DB::purge('master_temp');
  142. } catch (\Exception $cleanupError) {
  143. // Ignore cleanup errors
  144. }
  145. throw $e;
  146. } finally {
  147. set_time_limit($originalTimeout);
  148. }
  149. }
  150. private function sendAccountActivationEmailSafely($user)
  151. {
  152. try {
  153. Log::info('Attempting to send activation email', ['user_id' => $user->id]);
  154. $emailData = [
  155. 'name' => $user->name,
  156. 'email' => $user->email,
  157. 'login_url' => url('/'),
  158. 'activation_time' => now()->format('d/m/Y H:i'),
  159. 'platform_name' => 'Leezard.cloud'
  160. ];
  161. $originalTimeout = ini_get('max_execution_time');
  162. set_time_limit(15);
  163. Mail::send('emails.account-activated', $emailData, function ($message) use ($user) {
  164. $message->to($user->email, $user->name)
  165. ->subject('Il tuo account è attivo – Benvenuto in Leezard.cloud')
  166. ->from(config('mail.from.address'), config('mail.from.name'));
  167. });
  168. set_time_limit($originalTimeout);
  169. Log::info('Activation email sent successfully', [
  170. 'user_id' => $user->id,
  171. 'email' => $user->email
  172. ]);
  173. } catch (\Exception $e) {
  174. Log::error('Failed to send activation email (non-critical)', [
  175. 'user_id' => $user->id,
  176. 'email' => $user->email,
  177. 'error' => $e->getMessage()
  178. ]);
  179. }
  180. }
  181. }