change-password.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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 (session_status() === PHP_SESSION_NONE) {
  6. session_start();
  7. }
  8. requireLogin();
  9. $pageTitle = 'Change Password';
  10. $siteName = 'Crop Monitor';
  11. $errors = [];
  12. $success = false;
  13. if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  14. if (!verifyCsrfToken($_POST['csrf_token'] ?? '')) {
  15. $errors[] = 'Invalid security token. Please try again.';
  16. } else {
  17. $oldPassword = $_POST['password_old'] ?? '';
  18. $newPassword = $_POST['password_new'] ?? '';
  19. $confirm = $_POST['password_new_confirm'] ?? '';
  20. if ($oldPassword === '') {
  21. $errors[] = 'Current password is required.';
  22. }
  23. if (strlen($newPassword) < 8) {
  24. $errors[] = 'New password must be at least 8 characters.';
  25. }
  26. if ($newPassword !== $confirm) {
  27. $errors[] = 'New passwords do not match.';
  28. }
  29. if (empty($errors)) {
  30. if (changePassword(getCurrentUserId(), $oldPassword, $newPassword)) {
  31. regenerateCsrfToken();
  32. $success = true;
  33. } else {
  34. $errors[] = 'Current password is incorrect.';
  35. }
  36. }
  37. }
  38. }
  39. include __DIR__ . '/../layouts/header.php';
  40. include __DIR__ . '/../layouts/navbar.php';
  41. ?>
  42. <div id="layoutSidenav">
  43. <div id="layoutSidenav_nav">
  44. <?php include __DIR__ . '/../layouts/sidebar.php'; ?>
  45. </div>
  46. <div id="layoutSidenav_content">
  47. <main>
  48. <div class="container-fluid px-4">
  49. <h1 class="mt-4"><?= htmlspecialchars($pageTitle, ENT_QUOTES, 'UTF-8') ?></h1>
  50. <ol class="breadcrumb mb-4">
  51. <li class="breadcrumb-item"><a href="/dashboard/dashboard.php">Dashboard</a></li>
  52. <li class="breadcrumb-item active">Change Password</li>
  53. </ol>
  54. <div class="row justify-content-center">
  55. <div class="col-xl-6 col-lg-8">
  56. <div class="card shadow mb-4">
  57. <div class="card-header py-3">
  58. <h6 class="m-0 fw-bold text-success">Update Your Password</h6>
  59. </div>
  60. <div class="card-body">
  61. <?php if ($success): ?>
  62. <div class="alert alert-success" role="alert">
  63. <i class="fas fa-check-circle me-2"></i>Your password has been updated successfully.
  64. </div>
  65. <?php endif; ?>
  66. <?php if (!empty($errors)): ?>
  67. <div class="alert alert-danger" role="alert">
  68. <ul class="mb-0">
  69. <?php foreach ($errors as $e): ?>
  70. <li><?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8') ?></li>
  71. <?php endforeach; ?>
  72. </ul>
  73. </div>
  74. <?php endif; ?>
  75. <form method="post" action="/login/change-password.php">
  76. <input type="hidden" name="csrf_token"
  77. value="<?= htmlspecialchars(generateCsrfToken(), ENT_QUOTES, 'UTF-8') ?>">
  78. <div class="mb-3">
  79. <label for="password_old" class="form-label">Current Password</label>
  80. <input type="password" class="form-control" id="password_old"
  81. name="password_old" placeholder="Current password" required>
  82. </div>
  83. <div class="mb-3">
  84. <label for="password_new" class="form-label">New Password</label>
  85. <input type="password" class="form-control" id="password_new"
  86. name="password_new" placeholder="New password (min 8 characters)" required>
  87. </div>
  88. <div class="mb-3">
  89. <label for="password_new_confirm" class="form-label">Confirm New Password</label>
  90. <input type="password" class="form-control" id="password_new_confirm"
  91. name="password_new_confirm" placeholder="Repeat new password" required>
  92. </div>
  93. <button type="submit" class="btn btn-success">
  94. <i class="fas fa-key me-1"></i>Change Password
  95. </button>
  96. <a href="/dashboard/dashboard.php" class="btn btn-secondary ms-2">Cancel</a>
  97. </form>
  98. </div>
  99. </div>
  100. </div>
  101. </div>
  102. </div><!-- /container-fluid -->
  103. <?php include __DIR__ . '/../layouts/footer.php'; ?>