forgot-password.php 4.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. <?php
  2. require_once __DIR__ . '/../config/database.php';
  3. require_once __DIR__ . '/../lib/auth.php';
  4. require_once __DIR__ . '/../lib/csrf.php';
  5. require_once __DIR__ . '/../vendor/autoload.php';
  6. require_once __DIR__ . '/../lib/mailer.php';
  7. if (isLoggedIn()) {
  8. header('Location: /dashboard/dashboard.php');
  9. exit;
  10. }
  11. $sent = false;
  12. $error = '';
  13. if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  14. if (!verifyCsrfToken($_POST['csrf_token'] ?? '')) {
  15. $error = 'Invalid request. Please try again.';
  16. } else {
  17. $email = trim($_POST['email'] ?? '');
  18. if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
  19. $error = 'Please enter a valid email address.';
  20. } else {
  21. // createPasswordResetToken returns null if email not found,
  22. // but we show the same success message to avoid email enumeration.
  23. $token = createPasswordResetToken($email);
  24. if ($token !== null) {
  25. sendPasswordResetEmail($email, $token);
  26. }
  27. $sent = true; // Always show success to prevent email enumeration
  28. }
  29. }
  30. }
  31. $pageTitle = 'Forgot Password';
  32. include __DIR__ . '/_head.php';
  33. ?>
  34. <div class="container">
  35. <div class="row justify-content-center">
  36. <div class="col-xl-10 col-lg-12 col-md-9">
  37. <div class="card o-hidden border-0 shadow-lg my-5">
  38. <div class="card-body p-0">
  39. <div class="row">
  40. <div class="col-lg-6 d-none d-lg-block bg-login-image"></div>
  41. <div class="col-lg-6">
  42. <div class="p-5">
  43. <div class="text-center mb-4">
  44. <h1 class="h4 text-gray-900">Forgot Your Password?</h1>
  45. <p class="text-muted small">Enter your email and we'll send you a reset link.</p>
  46. </div>
  47. <?php if ($sent): ?>
  48. <div class="alert alert-success" role="alert">
  49. If that email is registered, a reset link has been sent. Please check your inbox.
  50. </div>
  51. <?php else: ?>
  52. <?php if ($error !== ''): ?>
  53. <div class="alert alert-danger"><?= htmlspecialchars($error, ENT_QUOTES, 'UTF-8') ?></div>
  54. <?php endif; ?>
  55. <form method="POST" action="/login/forgot-password.php" novalidate>
  56. <input type="hidden" name="csrf_token" value="<?= generateCsrfToken() ?>">
  57. <div class="mb-3">
  58. <input type="email" name="email" class="form-control form-control-user"
  59. placeholder="Email Address" required autofocus
  60. value="<?= htmlspecialchars($_POST['email'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
  61. </div>
  62. <button type="submit" class="btn btn-success btn-user w-100 mb-3">
  63. Send Reset Link
  64. </button>
  65. </form>
  66. <?php endif; ?>
  67. <hr>
  68. <div class="text-center">
  69. <a class="small" href="/login/register.php">Create an Account!</a>
  70. </div>
  71. <div class="text-center">
  72. <a class="small" href="/login/login.php">Already have an account? Login!</a>
  73. </div>
  74. </div>
  75. </div>
  76. </div>
  77. </div>
  78. </div>
  79. </div>
  80. </div>
  81. </div>
  82. <?php include __DIR__ . '/_foot.php'; ?>