user(); $pendingSecret = session('two_factor_pending_secret'); $pendingUri = null; if ($pendingSecret && $user) { $pendingUri = app(TotpService::class)->buildOtpAuthUri( config('app.name', 'NetGescon'), (string) $user->email, (string) $pendingSecret ); } return view('profile.edit', [ 'user' => $user, 'twoFactorPendingSecret' => $pendingSecret, 'twoFactorPendingUri' => $pendingUri, ]); } /** * Update the user's profile information. */ public function update(ProfileUpdateRequest $request): RedirectResponse { $request->user()->fill($request->validated()); if ($request->user()->isDirty('email')) { $request->user()->email_verified_at = null; } $request->user()->save(); return Redirect::route('profile.edit')->with('status', 'profile-updated'); } /** * Delete the user's account. */ public function destroy(Request $request): RedirectResponse { $request->validateWithBag('userDeletion', [ 'password' => ['required', 'current_password'], ]); $user = $request->user(); Auth::logout(); $user->delete(); $request->session()->invalidate(); $request->session()->regenerateToken(); return Redirect::to('/'); } public function twoFactorEnable(Request $request, TotpService $totp): RedirectResponse { $user = $request->user(); if (! $user) { abort(403); } $secret = $totp->generateSecret(); $request->session()->put('two_factor_pending_secret', $secret); return Redirect::route('profile.edit')->with('status', 'two-factor-pending'); } public function twoFactorConfirm(Request $request, TotpService $totp): RedirectResponse { $request->validate([ 'code' => ['required', 'digits:6'], ]); $user = $request->user(); $secret = (string) $request->session()->get('two_factor_pending_secret', ''); if (! $user || $secret === '') { throw ValidationException::withMessages([ 'code' => 'Sessione 2FA scaduta. Riavvia la procedura.', ]); } if (! $totp->verify($secret, (string) $request->input('code'))) { throw ValidationException::withMessages([ 'code' => 'Codice 2FA non valido.', ]); } $recoveryCodes = collect(range(1, 8)) ->map(fn() => strtoupper(bin2hex(random_bytes(4)))) ->all(); $user->forceFill([ 'two_factor_secret' => Crypt::encryptString($secret), 'two_factor_recovery_codes' => Crypt::encryptString(json_encode($recoveryCodes)), 'two_factor_confirmed_at' => now(), ])->save(); $request->session()->forget('two_factor_pending_secret'); return Redirect::route('profile.edit')->with('status', 'two-factor-enabled'); } public function twoFactorDisable(Request $request): RedirectResponse { $request->validate([ 'password' => ['required', 'current_password'], ]); $user = $request->user(); if (! $user) { abort(403); } $user->forceFill([ 'two_factor_secret' => null, 'two_factor_recovery_codes' => null, 'two_factor_confirmed_at' => null, ])->save(); $request->session()->forget('two_factor_pending_secret'); return Redirect::route('profile.edit')->with('status', 'two-factor-disabled'); } }