reset-password.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. require_once __DIR__ . '/../config/database.php';
  3. require_once __DIR__ . '/../lib/auth.php';
  4. require_once __DIR__ . '/../lib/csrf.php';
  5. if (isLoggedIn()) {
  6. header('Location: /dashboard/dashboard.php');
  7. exit;
  8. }
  9. $token = trim($_GET['token'] ?? '');
  10. $error = '';
  11. $done = false;
  12. // Validate token on page load
  13. if ($token === '') {
  14. header('Location: /login/forgot-password.php');
  15. exit;
  16. }
  17. $tokenEmail = validatePasswordResetToken($token);
  18. if ($tokenEmail === null) {
  19. $error = 'This reset link is invalid or has expired. Please request a new one.';
  20. }
  21. if ($_SERVER['REQUEST_METHOD'] === 'POST' && $tokenEmail !== null) {
  22. if (!verifyCsrfToken($_POST['csrf_token'] ?? '')) {
  23. $error = 'Invalid request. Please try again.';
  24. } else {
  25. $password = $_POST['password'] ?? '';
  26. $password2 = $_POST['password_confirm'] ?? '';
  27. if (strlen($password) < 8) {
  28. $error = 'Password must be at least 8 characters.';
  29. } elseif ($password !== $password2) {
  30. $error = 'Passwords do not match.';
  31. } else {
  32. if (resetPassword($token, $password)) {
  33. $done = true;
  34. } else {
  35. $error = 'This reset link is invalid or has expired. Please request a new one.';
  36. }
  37. }
  38. }
  39. }
  40. $pageTitle = 'Reset Password';
  41. include __DIR__ . '/_head.php';
  42. ?>
  43. <div class="container">
  44. <div class="row justify-content-center">
  45. <div class="col-xl-10 col-lg-12 col-md-9">
  46. <div class="card o-hidden border-0 shadow-lg my-5">
  47. <div class="card-body p-0">
  48. <div class="row">
  49. <div class="col-lg-6 d-none d-lg-block bg-login-image"></div>
  50. <div class="col-lg-6">
  51. <div class="p-5">
  52. <div class="text-center mb-4">
  53. <h1 class="h4 text-gray-900">Reset Your Password</h1>
  54. </div>
  55. <?php if ($done): ?>
  56. <div class="alert alert-success" role="alert">
  57. Your password has been reset.
  58. <a href="/login/login.php?reset=1">Click here to log in.</a>
  59. </div>
  60. <?php elseif ($error !== '' && $tokenEmail === null): ?>
  61. <div class="alert alert-danger"><?= htmlspecialchars($error, ENT_QUOTES, 'UTF-8') ?></div>
  62. <div class="text-center">
  63. <a href="/login/forgot-password.php">Request a new reset link</a>
  64. </div>
  65. <?php else: ?>
  66. <?php if ($error !== ''): ?>
  67. <div class="alert alert-danger"><?= htmlspecialchars($error, ENT_QUOTES, 'UTF-8') ?></div>
  68. <?php endif; ?>
  69. <form method="POST" action="/login/reset-password.php?token=<?= urlencode($token) ?>" novalidate>
  70. <input type="hidden" name="csrf_token" value="<?= generateCsrfToken() ?>">
  71. <div class="mb-3">
  72. <input type="password" name="password" class="form-control form-control-user"
  73. placeholder="New Password (min 8 chars)" required autofocus>
  74. </div>
  75. <div class="mb-3">
  76. <input type="password" name="password_confirm" class="form-control form-control-user"
  77. placeholder="Confirm New Password" required>
  78. </div>
  79. <button type="submit" class="btn btn-success btn-user btn-block w-100 mb-3">
  80. Set New Password
  81. </button>
  82. </form>
  83. <?php endif; ?>
  84. <hr>
  85. <div class="text-center">
  86. <a class="small" href="/login/login.php">Back to Login</a>
  87. </div>
  88. </div>
  89. </div>
  90. </div>
  91. </div>
  92. </div>
  93. </div>
  94. </div>
  95. </div>
  96. <?php include __DIR__ . '/_foot.php'; ?>