From 18ec3a714374a7196aadba7c5338d01ced47ff7c Mon Sep 17 00:00:00 2001 From: Myron Blair Date: Wed, 3 Jun 2026 03:54:16 +0000 Subject: [PATCH] =?UTF-8?q?Fix=20broken=20password=20reset=20INSERT=20?= =?UTF-8?q?=E2=80=94=20SQL=20syntax=20error=20and=20wrong=20token=20value?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The INSERT had two compounding bugs: 1. ".?" in the VALUES clause — a PHP dot inside a double-quoted string is a literal character, not concatenation. MySQL saw it as a syntax error and the INSERT always failed silently (no try/catch). 2. The token column had the literal string __reset__ hardcoded instead of a ? placeholder, so even if the INSERT had run, the real random token would never have been stored — the reset link always invalid. Fix: VALUES ("__reset__","",?,?,?,?) with execute(alias,email,token,exp) giving 4 placeholders for 4 params, all columns correctly bound. --- api/admin.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api/admin.php b/api/admin.php index 3333c82..575ea31 100644 --- a/api/admin.php +++ b/api/admin.php @@ -368,13 +368,12 @@ switch ($action) { // Generate reset token — reuse pending_registrations pattern $token = bin2hex(random_bytes(32)); $exp = date('Y-m-d H:i:s', time() + 3600); // 1 hour - db()->prepare("INSERT INTO pending_registrations (username,password,alias,email,token,expires_at) VALUES ('__reset__','',''.?,?,'__reset__',?) ON DUPLICATE KEY UPDATE token=VALUES(token),expires_at=VALUES(expires_at)")->execute([$user['alias'],$user['email'],$token,$exp]); + db()->prepare("INSERT INTO pending_registrations (username,password,alias,email,token,expires_at) VALUES ('__reset__','',?,?,?,?) ON DUPLICATE KEY UPDATE token=VALUES(token),expires_at=VALUES(expires_at)")->execute([$user['alias'],$user['email'],$token,$exp]); // Simple reset email $resetUrl = rtrim(SITE_URL,'/') . '/reset_password.php?token=' . urlencode($token); $subject = SITE_NAME . ' — Password Reset Request'; $body = "Hi {$user['alias']},\n\nA password reset was requested for your account.\n\nClick here to reset: {$resetUrl}\n\nExpires in 1 hour. If you didn't request this, ignore this email.\n\n— " . SITE_NAME; - $headers = "From: " . MAIL_FROM_NAME . " <" . MAIL_FROM . ">\r\nReply-To: " . MAIL_REPLY_TO; - mail($user['email'], $subject, $body, $headers, '-f' . MAIL_FROM); + cybermailSend($user['email'], $user['alias'], $subject, $body, '', ['password-reset']); echo json_encode(['success'=>true]); break;