Fix admin organization proof image preview path and implement forgot password feature with rate limiting and check email warning

This commit is contained in:
ilham_gmail
2026-06-11 20:38:28 +07:00
parent cbbd683470
commit b6f150ef86
5 changed files with 219 additions and 49 deletions
@@ -30,6 +30,8 @@ try {
last_attempt_at DATETIME NOT NULL,
locked_until DATETIME NULL
)");
$conn->query("ALTER TABLE verification_attempts ADD COLUMN IF NOT EXISTS code_hash VARCHAR(128) NULL");
$conn->query("ALTER TABLE verification_attempts ADD COLUMN IF NOT EXISTS expires_at DATETIME NULL");
} catch (Exception $e) {}
$nowStr = date('Y-m-d H:i:s');
@@ -77,6 +79,7 @@ if($row){
// Generate 6-digit code
$verificationCode = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
$codeHash = hash('sha256', $verificationCode);
$expiresAt = date('Y-m-d H:i:s', $nowTime + 15 * 60); // 15 minutes expiry
$mailSuccess = false;
try{
@@ -92,15 +95,15 @@ if($row){
$newAttempts = ($row['locked_until'] && $nowTime >= strtotime($row['locked_until'])) ? 1 : ($row['attempts'] + 1);
$newLockedUntil = ($newAttempts >= 3) ? date('Y-m-d H:i:s', $nowTime + 24 * 3600) : null;
$up = $conn->prepare("UPDATE verification_attempts SET attempts = ?, last_attempt_at = ?, locked_until = ? WHERE email = ?");
$up->bind_param('isss', $newAttempts, $nowStr, $newLockedUntil, $email);
$up = $conn->prepare("UPDATE verification_attempts SET attempts = ?, last_attempt_at = ?, locked_until = ?, code_hash = ?, expires_at = ? WHERE email = ?");
$up->bind_param('isssss', $newAttempts, $nowStr, $newLockedUntil, $codeHash, $expiresAt, $email);
$up->execute();
$up->close();
} else {
$one = 1;
$nullVal = null;
$ins = $conn->prepare("INSERT INTO verification_attempts (email, attempts, last_attempt_at, locked_until) VALUES (?, ?, ?, ?)");
$ins->bind_param('siss', $email, $one, $nowStr, $nullVal);
$ins = $conn->prepare("INSERT INTO verification_attempts (email, attempts, last_attempt_at, locked_until, code_hash, expires_at) VALUES (?, ?, ?, ?, ?, ?)");
$ins->bind_param('sissss', $email, $one, $nowStr, $nullVal, $codeHash, $expiresAt);
$ins->execute();
$ins->close();
}