diff --git a/app/Http/Controllers/PasswordSecurityController.php b/app/Http/Controllers/PasswordSecurityController.php index 9914b8b13..4f196aa4c 100644 --- a/app/Http/Controllers/PasswordSecurityController.php +++ b/app/Http/Controllers/PasswordSecurityController.php @@ -69,16 +69,29 @@ class PasswordSecurityController extends Controller $user->passwordSecurity->google2fa_enable = 1; $user->passwordSecurity->save(); + // Check if we should redirect to profile page + if ($request->has('redirect_to_profile')) { + return redirect()->to('profileedit#security')->with('success_2fa', '2FA is Enabled Successfully.'); + } + return redirect()->to('2fa')->with('success', '2FA is Enabled Successfully.'); } + // Check if we should redirect to profile page on failure as well + if ($request->has('redirect_to_profile')) { + return redirect()->to('profileedit#security')->with('error_2fa', 'Invalid Verification Code, Please try again.'); + } + return redirect()->to('2fa')->with('error', 'Invalid Verification Code, Please try again.'); } public function disable2fa(Disable2faPasswordSecurityRequest $request): \Illuminate\Routing\Redirector|RedirectResponse|\Illuminate\Contracts\Foundation\Application { if (! (Hash::check($request->get('current-password'), $request->user()->password))) { - // The passwords matches + // Password doesn't match + if ($request->has('redirect_to_profile') || $request->has('from_profile')) { + return redirect()->to('profileedit#security')->with('error_2fa', 'Your password does not match with your account password. Please try again.'); + } return redirect()->back()->with('error', 'Your password does not match with your account password. Please try again.'); } @@ -87,6 +100,11 @@ class PasswordSecurityController extends Controller $user->passwordSecurity->google2fa_enable = 0; $user->passwordSecurity->save(); + // Check if this request is from the profile edit page + if ($request->has('redirect_to_profile') || $request->has('from_profile')) { + return redirect()->to('profileedit#security')->with('success_2fa', '2FA is now Disabled.'); + } + return redirect()->to('2fa')->with('success', '2FA is now Disabled.'); } @@ -182,4 +200,60 @@ class PasswordSecurityController extends Controller return app('smarty.view')->display($theme.'/2fa_verify.tpl'); } + + /** + * Handle disabling 2FA directly from profile page to avoid form conflicts. + * This route is specifically for the profile page 2FA section. + */ + public function profileDisable2fa(Request $request): RedirectResponse + { + $request->validate([ + 'current-password' => 'required', + ]); + + if (! (Hash::check($request->get('current-password'), $request->user()->password))) { + return redirect()->to('profileedit#security')->with('error_2fa', 'Your password does not match with your account password. Please try again.'); + } + + $user = $request->user(); + if ($user->passwordSecurity) { + $user->passwordSecurity->google2fa_enable = 0; + $user->passwordSecurity->save(); + } + + return redirect()->to('profileedit#security')->with('success_2fa', '2FA is now Disabled.'); + } + + /** + * Show the 2FA enable form on a dedicated page + */ + public function showEnable2faForm(Request $request): Application|View|Factory|\Illuminate\Contracts\Foundation\Application + { + $user = $request->user(); + $success = $request->session()->get('success'); + $error = $request->session()->get('error'); + + $google2fa_url = ''; + if ($user->passwordSecurity()->exists()) { + $google2fa_url = \Google2FA::getQRCodeInline( + config('app.name'), + $user->email, + $user->passwordSecurity->google2fa_secret + ); + } + + return view('themes.Gentele.2fa_enable', compact('user', 'google2fa_url', 'success', 'error')); + } + + /** + * Show the 2FA disable form on a dedicated page + */ + public function showDisable2faForm(Request $request): Application|View|Factory|\Illuminate\Contracts\Foundation\Application + { + $user = $request->user(); + $success = $request->session()->get('success'); + $error = $request->session()->get('error'); + + return view('themes.Gentele.2fa_disable', compact('user', 'success', 'error')); + } } diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 584a4196f..f1d72da93 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -117,6 +117,18 @@ class ProfileController extends BasePageController } $errorStr = ''; + $success_2fa = $request->session()->get('success'); + $error_2fa = $request->session()->get('error'); + + // Generate 2FA QR code URL if 2FA is set up but not enabled + $google2fa_url = ''; + if ($this->userdata->passwordSecurity()->exists() && !$this->userdata->passwordSecurity->google2fa_enable) { + $google2fa_url = \Google2FA::getQRCodeInline( + config('app.name'), + $this->userdata->email, + $this->userdata->passwordSecurity->google2fa_secret + ); + } switch ($action) { case 'newapikey': @@ -247,6 +259,9 @@ class ProfileController extends BasePageController $this->smarty->assign('error', $errorStr); $this->smarty->assign('user', $this->userdata); $this->smarty->assign('userexccat', User::getCategoryExclusionById($userid)); + $this->smarty->assign('success_2fa', $success_2fa); + $this->smarty->assign('error_2fa', $error_2fa); + $this->smarty->assign('google2fa_url', $google2fa_url); $meta_title = 'Edit User Profile'; $meta_keywords = 'edit,profile,user,details'; diff --git a/app/Http/Controllers/ProfileSecurityController.php b/app/Http/Controllers/ProfileSecurityController.php new file mode 100644 index 000000000..0ea33f6c9 --- /dev/null +++ b/app/Http/Controllers/ProfileSecurityController.php @@ -0,0 +1,75 @@ +validate([ + 'current_password' => 'required', + ]); + + // Check if password is correct + if (!Hash::check($validated['current_password'], Auth::user()->password)) { + if ($request->expectsJson() || $request->ajax()) { + return response()->json([ + 'success' => false, + 'message' => 'Your password does not match. Please try again.' + ]); + } + + return redirect() + ->to('profileedit#security') + ->with('error_2fa', 'Your password does not match. Please try again.'); + } + + // Get the user and disable 2FA + $user = Auth::user(); + if ($user->passwordSecurity) { + $user->passwordSecurity->google2fa_enable = 0; + $user->passwordSecurity->save(); + + if ($request->expectsJson() || $request->ajax()) { + return response()->json([ + 'success' => true, + 'message' => '2FA has been successfully disabled.' + ]); + } + + return redirect() + ->to('profileedit#security') + ->with('success_2fa', '2FA has been successfully disabled.'); + } + + if ($request->expectsJson() || $request->ajax()) { + return response()->json([ + 'success' => false, + 'message' => 'No 2FA configuration found for this user.' + ]); + } + + return redirect() + ->to('profileedit#security') + ->with('error_2fa', 'No 2FA configuration found for this user.'); + } +} diff --git a/resources/views/themes/Gentele/2fa_disable.tpl b/resources/views/themes/Gentele/2fa_disable.tpl new file mode 100644 index 000000000..3113d7506 --- /dev/null +++ b/resources/views/themes/Gentele/2fa_disable.tpl @@ -0,0 +1,120 @@ + + +
+ + + +Remove the extra security layer from your account
+Please enter your current password to verify your identity:
+ +Add an extra layer of security to your account
+If you can't scan the QR code, please set up manually using the code provided.
+Add an extra layer of security to your account
Enable 2FA to add an additional layer of security to your account
+Your account is protected with an additional layer of security
+Two-factor authentication adds a second layer of security to your account. In addition to your password, you'll need a code from your authenticator app to sign in. This helps protect your account even if your password is compromised.
+