enforce(RateLimiter::identifier(), 'login'); try { $email = filterRequest('email') ?? ''; $password = filterRequest('password') ?? ''; $audience = filterRequest('aud') ?? ''; $allowed1 = getenv('allowedService1'); $allowed2 = getenv('allowedService2'); $allowedAudiences = array_values(array_filter([$allowed1, $allowed2])); if (empty($email) || empty($password) || empty($audience)) { jsonError('Email and password are required.', 400); } if (!in_array($audience, $allowedAudiences, true)) { jsonError('Invalid audience', 400); } $con = Database::get('main'); // استخدام user table ويفضل استخدام password_hash لاحقا مثل admin_users $stmt = $con->prepare("SELECT `id`, `password`, `email` FROM `users` WHERE email = :email LIMIT 1"); $stmt->execute([':email' => $email]); $user = $stmt->fetch(); $startTime = microtime(true); // دعم password_verify مع البقاء على التوافق مع كلمات السر القديمة (Plain Text) if ($user && (password_verify($password, $user['password']) || $user['password'] === $password)) { $limiter->reset(RateLimiter::identifier(), 'login'); $jwtService = new JwtService($redis); $jwt = $jwtService->generateAccessToken($user['id'], 'service', $audience); $refresh = $jwtService->generateRefreshToken($user['id']); jsonSuccess([ 'jwt' => $jwt, 'refresh_token' => $refresh['token'], 'expires_in' => 900 // أو 6600 كما كان في الكود الأصلي ]); } else { $elapsed = microtime(true) - $startTime; if ($elapsed < 0.1) usleep((int)((0.1 - $elapsed) * 1000000)); securityLog("Service login failed", ['email' => $email]); jsonError('Invalid email or password', 401); } } catch (PDOException $e) { securityLog("Service Login PDO Error", ['msg' => $e->getMessage()]); jsonError('Login failed: Database error', 500); } catch (Exception $e) { securityLog("Service Login Error", ['msg' => $e->getMessage()]); jsonError('Login failed: Server error', 500); }