input('email'); $password = $request->input('password'); if (!$email || !$password) { Response::error('يرجى إدخال البريد الإلكتروني وكلمة المرور', 'VALIDATION_ERROR', 422); return; } try { $result = $this->authService->login($email, $password); // 2FA Check if ($result['user']->totp_enabled) { Response::json([ 'success' => true, 'requires_2fa' => true, 'temp_token' => $result['access_token'] ]); return; } // Set refresh token in HttpOnly cookie setcookie('refresh_token', $result['refresh_token'], [ 'expires' => time() + (60 * 60 * 24 * 7), 'path' => '/api/v1/auth/refresh', 'httponly' => true, 'samesite' => 'Strict', 'secure' => true ]); unset($result['refresh_token']); Response::json([ 'success' => true, 'data' => $result, 'message' => 'تم تسجيل الدخول بنجاح' ]); } catch (Throwable $e) { Response::error($e->getMessage(), 'AUTH_FAILED', 401); } } public function me(Request $request): void { $db = \App\Core\Database::getInstance(); $stmt = $db->prepare("SELECT id, tenant_id, name, email, role, totp_enabled FROM users WHERE id = ?"); $stmt->execute([$request->user->user_id]); $user = $stmt->fetch(); Response::json([ 'success' => true, 'data' => $user ]); } public function logout(Request $request): void { // Clear refresh token cookie setcookie('refresh_token', '', [ 'expires' => time() - 3600, 'path' => '/api/v1/auth/refresh', 'httponly' => true, 'samesite' => 'Strict', 'secure' => true ]); Response::json([ 'success' => true, 'message' => 'تم تسجيل الخروج بنجاح' ]); } public function refresh(Request $request): void { $refreshToken = $_COOKIE['refresh_token'] ?? null; if (!$refreshToken) { Response::error('رمز التجديد مفقود', 'UNAUTHORIZED', 401); return; } try { $result = $this->authService->refresh($refreshToken); // Set new refresh token in HttpOnly cookie setcookie('refresh_token', $result['refresh_token'], [ 'expires' => time() + (60 * 60 * 24 * 7), 'path' => '/api/v1/auth/refresh', 'httponly' => true, 'samesite' => 'Strict', 'secure' => true ]); unset($result['refresh_token']); Response::json([ 'success' => true, 'data' => $result, 'message' => 'تم تجديد الجلسة بنجاح' ]); } catch (Throwable $e) { Response::error($e->getMessage(), 'REFRESH_FAILED', 401); } } public function register(Request $request): void { try { $result = $this->authService->register($request->getBody()); // Set refresh token in HttpOnly cookie setcookie('refresh_token', $result['refresh_token'], [ 'expires' => time() + (60 * 60 * 24 * 7), 'path' => '/api/v1/auth/refresh', 'httponly' => true, 'samesite' => 'Strict', 'secure' => true ]); unset($result['refresh_token']); Response::json([ 'success' => true, 'data' => $result, 'message' => 'تم إنشاء الحساب وتسجيل الدخول بنجاح' ]); } catch (Throwable $e) { Response::error($e->getMessage(), 'REGISTRATION_FAILED', 400); } } public function enable2FA(Request $request): void { $user = $request->user; $totpService = new \App\Services\TotpService(); $secret = $totpService->generateSecret(); $qrUrl = $totpService->getQrCodeUrl($user->email, $secret); Response::json([ 'success' => true, 'data' => [ 'secret' => $secret, 'qr_url' => $qrUrl ] ]); } public function verify2FA(Request $request): void { $data = $request->getBody(); $code = $data['code'] ?? ''; $secret = $data['secret'] ?? ''; $totpService = new \App\Services\TotpService(); if ($totpService->verify($secret, $code)) { $db = \App\Core\Database::getInstance(); $stmt = $db->prepare("UPDATE users SET totp_secret = ?, totp_enabled = 1 WHERE id = ?"); $stmt->execute([$secret, $request->user->user_id]); Response::json(['success' => true, 'message' => 'تم تفعيل التحقق الثنائي بنجاح']); } else { Response::error('رمز التحقق غير صحيح', 'INVALID_CODE', 400); } } public function disable2FA(Request $request): void { $db = \App\Core\Database::getInstance(); $stmt = $db->prepare("UPDATE users SET totp_secret = NULL, totp_enabled = 0 WHERE id = ?"); $stmt->execute([$request->user->user_id]); Response::json(['success' => true, 'message' => 'تم تعطيل التحقق الثنائي']); } }