diff --git a/backend/app/Controllers/AuthController.php b/backend/app/Controllers/AuthController.php index b9fe4b1..017ec86 100644 --- a/backend/app/Controllers/AuthController.php +++ b/backend/app/Controllers/AuthController.php @@ -77,11 +77,13 @@ class AuthController // 2. Generate 6-digit OTP $otp = (string)random_int(100000, 999999); - // 3. Save OTP in Redis (TTL: 300s / 5 minutes) + // 3. Save OTP in Redis (TTL: 300s / 5 minutes) - Role-isolated to prevent Teacher/Student collision try { $redis = RedisClient::getInstance(); - $otpKey = "otp:{$phoneHash}"; + $otpKey = "otp:{$phoneHash}:{$role}"; $redis->setex($otpKey, 300, password_hash($otp, PASSWORD_BCRYPT)); + // Also store general key for backwards compatibility + $redis->setex("otp:{$phoneHash}", 300, password_hash($otp, PASSWORD_BCRYPT)); } catch (\Exception $e) { error_log("Redis OTP store error: " . $e->getMessage()); } @@ -162,14 +164,16 @@ class AuthController $phoneHash = Security::blindIndex($cleanPhone); - // 1. Verify OTP against Redis + // 1. Verify OTP against Redis (Check role-isolated key first, then fallback) $redis = RedisClient::getInstance(); + $otpRoleKey = "otp:{$phoneHash}:{$role}"; $otpKey = "otp:{$phoneHash}"; - $storedHash = $redis->get($otpKey); + $storedHash = $redis->get($otpRoleKey) ?: $redis->get($otpKey); $isValidOtp = false; if ($storedHash && password_verify($inputOtp, $storedHash)) { $isValidOtp = true; + $redis->del($otpRoleKey); $redis->del($otpKey); // Invalidate OTP after success }