From 925df9b915b856b04515f6ec27e26dcfede1cdb1 Mon Sep 17 00:00:00 2001 From: Yasen Pramatarov Date: Mon, 7 Apr 2025 16:21:35 +0300 Subject: [PATCH] Adds credentials page --- app/pages/credentials.php | 159 +++++++++++++++++++++++ app/templates/credentials-2fa-setup.php | 109 ++++++++++++++++ app/templates/credentials-2fa-verify.php | 86 ++++++++++++ app/templates/credentials-manage.php | 100 ++++++++++++++ app/templates/credentials.php | 51 ++++++++ public_html/index.php | 1 + 6 files changed, 506 insertions(+) create mode 100644 app/pages/credentials.php create mode 100644 app/templates/credentials-2fa-setup.php create mode 100644 app/templates/credentials-2fa-verify.php create mode 100644 app/templates/credentials-manage.php create mode 100644 app/templates/credentials.php diff --git a/app/pages/credentials.php b/app/pages/credentials.php new file mode 100644 index 0000000..6c4e273 --- /dev/null +++ b/app/pages/credentials.php @@ -0,0 +1,159 @@ +verifyCsrfToken($_POST['csrf_token'] ?? '')) { + Feedback::flash('ERROR', 'DEFAULT', 'Invalid security token. Please try again.'); + header("Location: $app_root?page=credentials"); + exit(); + } + + // Apply rate limiting + require_once '../app/includes/rate_limit_middleware.php'; + checkRateLimit($db, 'credentials', $user_id); + + switch ($item) { + case '2fa': + require_once '../app/helpers/2fa.php'; + + switch ($action) { + case 'setup': + // Validate the setup code + $code = $_POST['code'] ?? ''; + $secret = $_POST['secret'] ?? ''; + + if ($userObject->enableTwoFactor($user_id, $secret, $code)) { + Feedback::flash('NOTICE', 'DEFAULT', 'Two-factor authentication has been enabled successfully.'); + header("Location: $app_root?page=credentials"); + exit(); + } else { + Feedback::flash('ERROR', 'DEFAULT', 'Invalid verification code. Please try again.'); + header("Location: $app_root?page=credentials&action=edit"); + exit(); + } + break; + + case 'verify': + $code = $_POST['code'] ?? ''; + if ($userObject->verifyTwoFactor($user_id, $code)) { + $_SESSION['2fa_verified'] = true; + header("Location: $app_root?page=dashboard"); + exit(); + } else { + Feedback::flash('ERROR', 'DEFAULT', 'Invalid verification code. Please try again.'); + header("Location: $app_root?page=credentials&action=verify"); + exit(); + } + break; + + case 'disable': + if ($userObject->disableTwoFactor($user_id)) { + Feedback::flash('NOTICE', 'DEFAULT', 'Two-factor authentication has been disabled.'); + } else { + Feedback::flash('ERROR', 'DEFAULT', 'Failed to disable two-factor authentication.'); + } + header("Location: $app_root?page=credentials"); + exit(); + break; + } + break; + + case 'password': + require_once '../app/classes/validator.php'; + + $validator = new Validator($_POST); + $rules = [ + 'current_password' => [ + 'required' => true, + 'min' => 8 + ], + 'new_password' => [ + 'required' => true, + 'min' => 8 + ], + 'confirm_password' => [ + 'required' => true, + 'matches' => 'new_password' + ] + ]; + + if (!$validator->validate($rules)) { + Feedback::flash('ERROR', 'DEFAULT', $validator->getFirstError()); + header("Location: $app_root?page=credentials"); + exit(); + } + + if ($userObject->changePassword($user_id, $_POST['current_password'], $_POST['new_password'])) { + Feedback::flash('NOTICE', 'DEFAULT', 'Password has been changed successfully.'); + } else { + Feedback::flash('ERROR', 'DEFAULT', 'Failed to change password. Please verify your current password.'); + } + header("Location: $app_root?page=credentials"); + exit(); + break; + } + +// no form submitted, show the templates +} else { + // Get user timezone for templates + $userTimezone = !empty($userDetails[0]['timezone']) ? $userDetails[0]['timezone'] : 'UTC'; + + // Generate CSRF token if not exists + require_once '../app/helpers/security.php'; + $security = SecurityHelper::getInstance(); + $security->generateCsrfToken(); + + // Get 2FA status for the template + $has2fa = $userObject->isTwoFactorEnabled($user_id); + + switch ($action) { + case 'edit': + if (!$has2fa) { + require_once '../app/helpers/2fa.php'; + $secret = $userObject->generateTwoFactorSecret(); + $qrCode = $userObject->generateTwoFactorQR($user_id, $secret); + $backupCodes = $userObject->generateBackupCodes(); + } + // Get any new feedback messages + include '../app/helpers/feedback.php'; + + // Load the 2FA setup template + include '../app/templates/credentials-2fa-setup.php'; + break; + + case 'verify': + // Get any new feedback messages + include '../app/helpers/feedback.php'; + + // Load the 2FA verification template + include '../app/templates/credentials-2fa-verify.php'; + break; + + default: + // Get any new feedback messages + include '../app/helpers/feedback.php'; + + // Load the combined management template + include '../app/templates/credentials-manage.php'; + } +} diff --git a/app/templates/credentials-2fa-setup.php b/app/templates/credentials-2fa-setup.php new file mode 100644 index 0000000..9f70586 --- /dev/null +++ b/app/templates/credentials-2fa-setup.php @@ -0,0 +1,109 @@ + + +
+
+
+
+
+

Set up two-factor authentication

+
+
+
+

Two-factor authentication adds an extra layer of security to your account. Once enabled, you'll need to enter both your password and a code from your authenticator app when signing in.

+
+ + +
+ +
+ + + +
+

1. Install an authenticator app

+

If you haven't already, install an authenticator app on your mobile device:

+
    +
  • Google Authenticator
  • +
  • Microsoft Authenticator
  • +
  • Authy
  • +
+ +

2. Scan the QR code

+

Open your authenticator app and scan this QR code:

+ +
+
+
+ Can't scan? Use this code instead:
+ +
+
+ +

3. Verify setup

+

Enter the 6-digit code from your authenticator app to verify the setup:

+ +
+
+ +
+ + + + +
+ +
+

Backup codes

+

+ Important: Save these backup codes in a secure place. + If you lose access to your authenticator app, you can use these codes to sign in. + Each code can only be used once. +

+
+ + + +
+ +
+
+ +
+

Click the button below to begin setting up two-factor authentication:

+ +
+ +
+
+
+
+
+ + + + + diff --git a/app/templates/credentials-2fa-verify.php b/app/templates/credentials-2fa-verify.php new file mode 100644 index 0000000..abcbcf3 --- /dev/null +++ b/app/templates/credentials-2fa-verify.php @@ -0,0 +1,86 @@ + + +
+
+
+
+
+

Two-factor authentication

+
+
+ +
+ +
+ + +

Enter the 6-digit code from your authenticator app:

+ +
+
+ +
+ + + + +
+ +
+

+ Lost access to your authenticator app?
+ + Use a backup code + +

+ +
+
+
+ + +
+ + + + +
+
+
+
+
+
+
+
+ + diff --git a/app/templates/credentials-manage.php b/app/templates/credentials-manage.php new file mode 100644 index 0000000..8c6aeaf --- /dev/null +++ b/app/templates/credentials-manage.php @@ -0,0 +1,100 @@ + + +
+
+
+ +
+
+

change password

+
+
+
+ + +
+ + +
+ +
+ + + minimum 8 characters +
+ +
+ + +
+ +
+ +
+
+
+
+ + +
+
+

two-factor authentication

+
+
+

Two-factor authentication adds an extra layer of security to your account. Once enabled, you'll need to enter both your password and a code from your authenticator app when signing in.

+ + +
+ two-factor authentication is enabled +
+
+ + +
+ +
+ two-factor authentication is not enabled +
+
+ + +
+ +
+
+
+
+
+ + diff --git a/app/templates/credentials.php b/app/templates/credentials.php new file mode 100644 index 0000000..ce49a17 --- /dev/null +++ b/app/templates/credentials.php @@ -0,0 +1,51 @@ + + +
+
+

Two-factor authentication

+
+
+ +
+
+

+ + Two-factor authentication is enabled +

+ + Your account is protected with an authenticator app + +
+
+ + + + +
+
+ +
+
+

+ + Two-factor authentication is not enabled +

+ + Add an extra layer of security to your account by requiring both your password and an authentication code + +
+
+ + + + +
+
+ +
+
diff --git a/public_html/index.php b/public_html/index.php index e7003ab..1def0d2 100644 --- a/public_html/index.php +++ b/public_html/index.php @@ -53,6 +53,7 @@ $allowed_urls = [ 'config', 'profile', + 'credentials', 'settings', 'security',