From 9815db29d021fa5d04335cfaee0953529fedc9b8 Mon Sep 17 00:00:00 2001 From: Myron Blair Date: Wed, 3 Jun 2026 03:56:17 +0000 Subject: [PATCH] =?UTF-8?q?Add=20reset=5Fpassword.php=20=E2=80=94=20passwo?= =?UTF-8?q?rd=20reset=20redemption=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handles the /reset_password.php?token=... URL generated by the admin send_password_reset action. Flow: - GET: validates token against pending_registrations (username=__reset__, not expired), shows set-new-password form - POST: re-validates token, enforces 6-char min + confirm match, bcrypt-hashes the new password, updates users.password by email, deletes the pending row to prevent reuse - Invalid/expired token shows a clear error with link back to home Matches the dark gaming aesthetic of verify.php. --- reset_password.php | 113 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 reset_password.php diff --git a/reset_password.php b/reset_password.php new file mode 100644 index 0000000..6d603b5 --- /dev/null +++ b/reset_password.php @@ -0,0 +1,113 @@ +prepare( + "SELECT * FROM pending_registrations WHERE token=? AND username='__reset__' AND expires_at > NOW()" + ); + $stmt->execute([$token]); + $pending = $stmt->fetch(); +} + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $token = trim($_POST['token'] ?? ''); + $password = $_POST['password'] ?? ''; + $confirm = $_POST['confirm'] ?? ''; + + // Re-fetch pending row inside POST to prevent token reuse after expiry + $stmt = db()->prepare( + "SELECT * FROM pending_registrations WHERE token=? AND username='__reset__' AND expires_at > NOW()" + ); + $stmt->execute([$token]); + $pending = $stmt->fetch(); + + if (!$pending) { + $error = 'This reset link has expired or already been used. Please request a new one.'; + } elseif (strlen($password) < 6) { + $error = 'Password must be at least 6 characters.'; + } elseif ($password !== $confirm) { + $error = 'Passwords do not match.'; + } else { + $hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 8]); + $updated = db()->prepare("UPDATE users SET password=? WHERE email=?") + ->execute([$hash, $pending['email']]); + db()->prepare("DELETE FROM pending_registrations WHERE token=?")->execute([$token]); + $success = true; + $pending = null; + } +} +?> + + + + + +<?= SITE_NAME ?> — Reset Password + + + + +
+ + + + +
Password Updated!
+

Your password has been reset successfully. You can now log in with your new password.

+ BACK TO LOGIN + + + +
Invalid Link
+

This password reset link is invalid or has expired.
Please request a new one from the app.

+ BACK TO HOME + + +
Reset Password
+

Enter a new password for your account.

+ + +
+ + +
+ +
+ + +
+
+ + +
+ +
+ +
+ +