Single-sign-on and self-serve account management. https://netsyms.biz/apps/accounthub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.php 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. /*
  3. * This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. */
  7. require_once __DIR__ . "/../required.php";
  8. if (empty($_GET['code']) || empty($_GET['redirect'])) {
  9. die("Bad request.");
  10. }
  11. // Delete old keys to keep the table small and tidy
  12. $database->delete("userloginkeys", ["expires[<]" => date("Y-m-d H:i:s")]);
  13. if (!$database->has("userloginkeys", ["AND" => ["key" => $_GET["code"]], "expires[>]" => date("Y-m-d H:i:s"), "uid" => null])) {
  14. header("Location: $_GET[redirect]");
  15. die("Invalid auth code.");
  16. }
  17. $APPINFO = $database->get("userloginkeys", ["appname", "appicon"], ["key" => $_GET["code"]]);
  18. $APPNAME = $APPINFO["appname"];
  19. $APPICON = $APPINFO["appicon"];
  20. if (empty($_SESSION['thisstep'])) {
  21. $_SESSION['thisstep'] = "username";
  22. }
  23. $error = "";
  24. function sendUserBack($code, $url, $uid) {
  25. global $database;
  26. $database->update("userloginkeys", ["uid" => $uid], ["key" => $code]);
  27. header("Location: $url");
  28. die("<a href=\"" . htmlspecialchars($url) . "\">Click here</a>");
  29. }
  30. if (!empty($_SESSION['check'])) {
  31. switch ($_SESSION['check']) {
  32. case "username":
  33. if (empty($_POST['username'])) {
  34. $_SESSION['thisstep'] = "username";
  35. break;
  36. }
  37. $user = User::byUsername($_POST['username']);
  38. if ($user->exists()) {
  39. $_SESSION['login_uid'] = $user->getUID();
  40. switch ($user->getStatus()->get()) {
  41. case AccountStatus::LOCKED_OR_DISABLED:
  42. $error = $Strings->get("account locked", false);
  43. break;
  44. case AccountStatus::TERMINATED:
  45. $error = $Strings->get("account terminated", false);
  46. break;
  47. case AccountStatus::ALERT_ON_ACCESS:
  48. $mail_resp = $user->sendAlertEmail();
  49. case AccountStatus::NORMAL:
  50. $_SESSION['thisstep'] = "password";
  51. break;
  52. case AccountStatus::CHANGE_PASSWORD:
  53. $_SESSION['thisstep'] = "change_password";
  54. break;
  55. }
  56. } else {
  57. $error = $Strings->get("Username not found.", false);
  58. }
  59. break;
  60. case "password":
  61. if (empty($_POST['password'])) {
  62. $_SESSION['thisstep'] = "password";
  63. break;
  64. }
  65. if (empty($_SESSION['login_uid'])) {
  66. $_SESSION['thisstep'] = "username";
  67. break;
  68. }
  69. $user = new User($_SESSION['login_uid']);
  70. if ($user->checkPassword($_POST['password'])) {
  71. $_SESSION['login_pwd'] = true;
  72. if ($user->has2fa()) {
  73. $_SESSION['thisstep'] = "totp";
  74. } else {
  75. sendUserBack($_GET['code'], $_GET['redirect'], $_SESSION['login_uid']);
  76. }
  77. } else {
  78. $error = $Strings->get("Password incorrect.", false);
  79. }
  80. break;
  81. case "change_password":
  82. if (empty($_POST['oldpassword']) || empty($_POST['newpassword']) || empty($_POST['newpassword2'])) {
  83. $_SESSION['thisstep'] = "change_password";
  84. $error = $Strings->get("Fill in all three boxes.", false);
  85. break;
  86. }
  87. $user = new User($_SESSION['login_uid']);
  88. try {
  89. $result = $user->changePassword($_POST['oldpassword'], $_POST['newpassword'], $_POST['newpassword2']);
  90. if ($result === TRUE) {
  91. if ($user->has2fa()) {
  92. $_SESSION['thisstep'] = "totp";
  93. } else {
  94. sendUserBack($_GET['code'], $_GET['redirect'], $_SESSION['login_uid']);
  95. }
  96. }
  97. } catch (PasswordMatchException $e) {
  98. $error = $Strings->get(MESSAGES["passwords_same"]["string"], false);
  99. } catch (PasswordMismatchException $e) {
  100. $error = $Strings->get(MESSAGES["new_password_mismatch"]["string"], false);
  101. } catch (IncorrectPasswordException $e) {
  102. $error = $Strings->get(MESSAGES["old_password_mismatch"]["string"], false);
  103. } catch (WeakPasswordException $e) {
  104. $error = $Strings->get(MESSAGES["weak_password"]["string"], false);
  105. }
  106. break;
  107. case "totp":
  108. if (empty($_POST['totp']) || empty($_SESSION['login_uid'])) {
  109. $_SESSION['thisstep'] = "username";
  110. break;
  111. }
  112. $user = new User($_SESSION['login_uid']);
  113. if ($user->check2fa($_POST['totp'])) {
  114. sendUserBack($_GET['code'], $_GET['redirect'], $_SESSION['login_uid']);
  115. } else {
  116. $error = $Strings->get("Code incorrect.", false);
  117. }
  118. break;
  119. }
  120. }
  121. include __DIR__ . "/parts/header.php";
  122. switch ($_SESSION['thisstep']) {
  123. case "username":
  124. require __DIR__ . "/parts/username.php";
  125. break;
  126. case "password":
  127. require __DIR__ . "/parts/password.php";
  128. break;
  129. case "change_password":
  130. require __DIR__ . "/parts/change_password.php";
  131. break;
  132. case "totp":
  133. require __DIR__ . "/parts/totp.php";
  134. break;
  135. }
  136. include __DIR__ . "/parts/footer.php";