WebOrbiton
v2.0.0.0

Publisium

87 lines · 2.8 KB
  1. <?php
  2. ​
  3. declare(strict_types=1);
  4. ​
  5. $accountId = (int) $currentUser['id'];
  6. $twoFactorEnabled = TwoFactor::isEnabled($currentUser);
  7. ​
  8. $confirmIdentity = static function () use ($currentUser, $accountId): ?string {
  9. $wait = LoginThrottle::secondsUntilAllowed('totp_manage', (string) $accountId);
  10. if ($wait > 0) {
  11. return LoginThrottle::message($wait);
  12. }
  13. ​
  14. $passwordValid = password_verify((string) ($_POST['password'] ?? ''), (string) $currentUser['password_hash']);
  15. if (!$passwordValid || !TwoFactor::verify($currentUser, (string) ($_POST['code'] ?? ''))) {
  16. LoginThrottle::recordFailure('totp_manage', (string) $accountId);
  17. return 'The password or the code doesn’t match. Try again.';
  18. }
  19. ​
  20. LoginThrottle::clear('totp_manage', (string) $accountId);
  21. ​
  22. return null;
  23. };
  24. ​
  25. if ($action === 'totp_begin') {
  26. if (!$twoFactorEnabled) {
  27. $_SESSION['totp_setup_secret'] = Totp::generateSecret();
  28. }
  29. ​
  30. return [null, 'success', true];
  31. }
  32. ​
  33. if ($action === 'totp_cancel') {
  34. unset($_SESSION['totp_setup_secret']);
  35. ​
  36. return [null, 'success', true];
  37. }
  38. ​
  39. if ($action === 'totp_confirm') {
  40. $secret = (string) ($_SESSION['totp_setup_secret'] ?? '');
  41. if ($twoFactorEnabled || $secret === '') {
  42. return ['That took too long. Please start the setup again.', 'error', false];
  43. }
  44. ​
  45. $wait = LoginThrottle::secondsUntilAllowed('totp_setup', (string) $accountId);
  46. if ($wait > 0) {
  47. return [LoginThrottle::message($wait), 'error', false];
  48. }
  49. ​
  50. $step = Totp::verify($secret, (string) ($_POST['code'] ?? ''), null);
  51. if ($step === null) {
  52. LoginThrottle::recordFailure('totp_setup', (string) $accountId);
  53. ​
  54. return ['That code didn’t work. Make sure the time on your phone is right and try again.', 'error', false];
  55. }
  56. ​
  57. LoginThrottle::clear('totp_setup', (string) $accountId);
  58. $_SESSION['totp_new_codes'] = TwoFactor::enable($accountId, $secret, $step);
  59. unset($_SESSION['totp_setup_secret']);
  60. ActivityLog::record('security.2fa_enabled', 'account', $accountId);
  61. ​
  62. return [null, 'success', true];
  63. }
  64. ​
  65. if ($action === 'totp_disable' || $action === 'totp_regenerate') {
  66. if (!$twoFactorEnabled) {
  67. return ['Two-factor authentication is already off.', 'error', false];
  68. }
  69. ​
  70. $problem = $confirmIdentity();
  71. if ($problem !== null) {
  72. return [$problem, 'error', false];
  73. }
  74. ​
  75. if ($action === 'totp_disable') {
  76. TwoFactor::disable($accountId);
  77. ActivityLog::record('security.2fa_disabled', 'account', $accountId);
  78. } else {
  79. $_SESSION['totp_new_codes'] = TwoFactor::regenerateRecoveryCodes($accountId);
  80. ActivityLog::record('security.2fa_recovery_codes', 'account', $accountId);
  81. }
  82. ​
  83. return [null, 'success', true];
  84. }
  85. ​
  86. return ['Something went wrong. Please try again.', 'error', false];
  87. ​