From b2aedf53dbf2b9a01bd037090291fcb38dd30ec5 Mon Sep 17 00:00:00 2001 From: KMINGON Date: Tue, 1 Jul 2025 01:05:07 +0900 Subject: [PATCH] =?UTF-8?q?[FEAT]:=20env=EB=A1=9C=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 48 ++++++++ .sensitive.example.json | 4 + setup.py | 2 +- src/lib/llm/prompt/__init__.py | 12 +- src/lib/llm/prompt/fallback/prompt.py | 152 ++++++++----------------- src/lib/llm/prompt/get_oauth/prompt.py | 2 +- 6 files changed, 107 insertions(+), 113 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c94d292 --- /dev/null +++ b/.env.example @@ -0,0 +1,48 @@ +# 권장 (다른 모델로 교체 가능) [다른 모델로 교체시 성능 보장 불가] +ANONYMIZED_TELEMETRY=false + +# ========== LLM ========== + +GOOGLE_API_KEY= +# 권장 (다른 모델로 교체 가능) [다른 모델로 교체시 성능 보장 불가] +GOOGLE_MODEL=gemini-2.5-flash +#GOOGLE_PLANNER_MODEL=gemini-2.5-flash # 왜 비활성화 되었나요? // Planner 모델이 오히려 문제를 일으키는 경우가 있어 비활성화했습니다. 필요시 활성화하세요. + +# min(INITIAL_BACKOFF * (2 ** try_cnt), MAX_BACKOFF)만큼 API가 실패시 대기합니다. +INITIAL_BACKOFF=60 +MAX_BACKOFF=600 + +#ENABLE_PLANNER_MODEL_OAUTH_LOGIN=true # OAuth 로그인 시 Planner 모델을 활성화합니다. +#ENABLE_PLANNER_MODEL_OAUTH_LIST=true # OAuth List를 찾을 때 Planner 모델을 활성화합니다. + +# ========== Monitoring ========== + +# 선택 +PROXY_HOST=127.0.0.1 +PROXY_PORT=11080 +BACKEND_URL=http://localhost:11081 + +# https://docs.browser-use.com/development/observability +# Lmnr 계정이 필요합니다. +# https://lmnr.ai/ +LMNR_PROJECT_API_KEY= + +# 브라우저 언어 설정 +LANG=en_US + +# ========= Account ========== + +GOOGLE_ID=whs.imnya.ng@gmail.com +GOOGLE_PASSWORD=Vb1Mz9pgjY8JVs + +NAVER_ID=oauth-j93es +NAVER_PASSWORD=whs31234 + +FACEBOOK_ID=01047183675 +FACEBOOK_PASSWORD=whs3oauth@ + +GITGUB_ID=imnyang-bot +GITHUB_PASSWORD=6PuVXCH9tpQLNm + +MICROSOFT_ID=whs.imnya.ng@gmail.com +MICROSOFT_PASSWORD=WHS123987 \ No newline at end of file diff --git a/.sensitive.example.json b/.sensitive.example.json index 2d2b6a9..e7840f2 100644 --- a/.sensitive.example.json +++ b/.sensitive.example.json @@ -34,5 +34,9 @@ "login.microsoftonline.com" : { "x_username": "whs.imnya.ng@gmail.com", "x_password": "WHS123987" + }, + "facebook.com":{ + "x_username": "01047183675", + "x_password": "whs3oauth@" } } \ No newline at end of file diff --git a/setup.py b/setup.py index 6cf42d8..551d91b 100644 --- a/setup.py +++ b/setup.py @@ -127,6 +127,6 @@ if __name__ == "__main__": print("=====================================================") # 5. .sensitive.json 생성 - setup_sensitive() + # setup_sensitive() print("=====================================================") print("🎉 초기 설정이 완료되었습니다! 이제 스크립트를 실행할 준비가 되었습니다.") diff --git a/src/lib/llm/prompt/__init__.py b/src/lib/llm/prompt/__init__.py index 1f9e97b..3d676a5 100644 --- a/src/lib/llm/prompt/__init__.py +++ b/src/lib/llm/prompt/__init__.py @@ -12,13 +12,13 @@ def get_prompt(type: str) -> tuple[str, Type[BaseModel]] | str: from lib.llm.prompt.get_oauth import prompt, model return prompt, model - elif type.lower() in ["google", "google account"]: - from lib.llm.prompt.google import prompt, model - return prompt, model + # elif type.lower() in ["google", "google account"]: + # from lib.llm.prompt.google import prompt, model + # return prompt, model - elif type.lower() in ["microsoft", "microsoftonline"]: - from lib.llm.prompt.microsoft import prompt, model - return prompt, model + # elif type.lower() in ["microsoft", "microsoftonline"]: + # from lib.llm.prompt.microsoft import prompt, model + # return prompt, model else: from lib.llm.prompt.fallback import model, prompt diff --git a/src/lib/llm/prompt/fallback/prompt.py b/src/lib/llm/prompt/fallback/prompt.py index 42b11e1..13226b0 100644 --- a/src/lib/llm/prompt/fallback/prompt.py +++ b/src/lib/llm/prompt/fallback/prompt.py @@ -1,122 +1,64 @@ +from dotenv import load_dotenv +import os + +load_dotenv() +google_id = os.getenv("GOOGLE_ID") +google_password = os.getenv("GOOGLE_PASSWORD") + +naver_id = os.getenv("NAVER_ID") +naver_password = os.getenv("NAVER_PASSWORD") + +facebook_id = os.getenv("FACEBOOK_ID") +facebook_password = os.getenv("FACEBOOK_PASSWORD") + +github_id = os.getenv("GITHUB_ID") +github_password = os.getenv("GITHUB_PASSWORD") + +microsoft_id = os.getenv("MICROSOFT_ID") +microsoft_password = os.getenv("MICROSOFT_PASSWORD") + # Extended planner prompt prompt = f""" -🎯 목적: 웹 자동화를 위한 **SSO 로그인 리디렉션 URL 수집** +You are a web automation agent. -📌 주의사항 (전제 조건) -- ❌ **검색 엔진(Google, Bing 등) 사용 금지** -- ✅ **초기 제공된 URL 내에서만 탐색** -- ❌ 직접 이동하거나 추측한 링크 클릭 금지 -- ⛔ 추측한 URL은 대답하거나 클릭하지 마세요 -- OAuth가 아닌 일반 로그인은 무시 -- OAuth가 없다면 **즉시 중단**하고 빈 배열 반환 +Your task is to visit the given domain and perform a full login via the **SSO Login button**, following all steps strictly as described below. ---- +Instructions: -## 🧩 Step 0: 페이지 차단(Block) 여부 확인 +1. If any cookie or privacy popups appear, dismiss or accept them. +2. Navigate through the site's UI to find the **login or sign-in page** (e.g., via buttons like "Log In", "Sign In", "Get Started"). +3. Click the **SSO login button**. +4. Check if the user is **already logged and immediately redirected back to the original site** without showing a login screen. + - ✅ If so, treat the login as successful and return immediately. +5. If login proceeds without interruptions, wait for redirection back to the original site and record the final URL. -초기 URL의 로그인 페이지에 접근하여 다음 사항을 점검합니다: +Credentials to use for login: +- Google → `{google_id}` / `{google_password}` +- Naver → `{naver_id}` / `{naver_password}` +- GitHub → `{github_id}` / `{github_password}` +- facebook → `{facebook_id}` / `{facebook_password}` +- Microsoft → `{microsoft_id}` / `{microsoft_password}` +If credentials for a provider are not provided, skip the login attempt for that provider. -- 🚫 페이지 차단됨 (Firewall, Access Denied 등) → 즉시 중단 -- 🔒 CAPTCHA는 통과 가능 (해결하고 계속 진행) -- ❗ 로그인 UI가 정상적으로 로드되지 않으면 중단 +Constraints: +- Do NOT use search engines or guess URLs. +- Do NOT proceed with login if: + - CAPTCHA or MFA appears +- If the user is already logged and redirected back automatically, stop there and report success. +- If the login page cannot be found, return "login_page_not_found". +- If the login button is not found, return "sso_not_found". +- If a page such as a sign-up page appears, consider it a successful login and terminate immediately. -📤 차단 시 즉시 종료 - ---- - -## 🔍 Step 1: 로그인 페이지 탐색 - -* 초기 URL에 접속하여 **클라이언트용 로그인 페이지**로 진입합니다. -* 쿠키 동의, 개인정보 안내 등 팝업은 무시하거나 닫고 계속 진행하세요. -* 페이지가 정상 로드되었다고 가정합니다. - ---- - -## 👀 Step 2: SSO 로그인 버튼 식별 - -아래 **OAuth SSO 버튼들만** 유효합니다: - -* ✅ Google, GitHub, Facebook, LinkedIn, Microsoft, Naver - -**유효한 버튼 기준**: - -* OAuth 인증 흐름을 실제로 트리거 -* `window.location` 또는 `` 또는 JS로 redirect가 발생 - -**제외 버튼들 (클릭 금지)**: - -* ❌ 일반 로그인, 패스키, 이메일/전화번호, 인증서 기반, 비밀번호 입력 - ---- - -## ✅ Step 3: 모든 SSO 버튼 클릭 및 로그인 시도 - -> 각 SSO 로그인 버튼을 클릭한 뒤 반드시 아래 절차를 **완전히 수행**해야 합니다. - -각 SSO 버튼에 대해 다음을 수행: - -1. 버튼 클릭 -2. ✅ 로그인 진행: - - 로그인 페이지에서 OAuth 인증을 완료합니다. - - sign in with your username(email) x_username and password is x_password - - 버튼같은게 안눌리면 새로고침을 해봐 - - **로그인 완료 후 authorize 등 버튼이 있으면 클릭** - - GitHub같은 경우 Authorize 버튼이 뜨는데 오래걸릴 수 있음, 기다려야 할 수도 있음 - - 만약 버튼을 눌러도 반응이 없을 경우 새로고침을 한번 해주세요. - - **OAuth Flow가 완료되면 (callback URL 도달 또는 인증 완료) 즉시 작업 종료** -4. 로그인이 성공하면 모두 쿠키를 삭제하고 다음 SSO 버튼을 클릭합니다. -5. 다음 SSO 버튼으로 반복 진행 - -쿠키 삭제 방법: -chrome://settings/clearBrowserData에 들어가서 삭제해주세요. - -🛑 절대 아래와 같이 해석하지 말 것: -- ❌ 버튼 클릭 후 페이지 로딩만 기다리고 돌아가기 -- ❌ URL 저장 없이 go_back() 호출 - ---- - -### ✨ 추가 안전 장치: "뒤로가기(go_back) 호출 조건" 제한 - -```text -🛑 뒤로가기(go_back)은 다음 조건이 모두 충족될 때만 사용 => 다만 로그인 실패 시, 뒤로가기 수행: -- ✅ 로그인 흐름이 완료됨 (예: redirect back to app, or callback URL) -- ✅ 현재 리디렉션 URL이 수집됨 -- ✅ 결과에 저장 후 다음 버튼 탐색을 위해 복귀 필요할 때 -``` - ---- - -## 🚫 Step 4: 버튼 없음 또는 예외 발생 시 - -* 유효한 SSO 버튼이 **전혀 없을 경우** -* 예외, 오류 등 발생 시 - --> 즉시 중단 - ---- - - -최종 반환: +Final Output: Return the result in the following format only: ```json {{ - "msg": "Google login completed", - "status": "success" | "already_logged_in" | "mfa_required" | "window_blocked" | "idpw_required" | "blocked" | "sso_not_found" | "login_page_not_found", + "msg": "login completed", + "status": "success" | "already_logged_in" | "mfa_required" | "captcha_triggered" | "window_blocked" | "idpw_required" | "sso_not_found" | "login_page_not_found", "final_url": "" }} ``` ---- - -## 📎 중요 규칙 요약 - -* ✅ **모든 SSO 로그인은 반드시 실행** (가능한 버튼은 모두 클릭) -* 🔁 단계는 반드시 순서대로 진행 -* 🔐 로그인은 쿠키/세션으로 유지된 상태에서 수행 -* 👀 직접 OAuth Providor ID/PW를 입력하여도 됨 가지고 있다면 -* ⛔ 추측한 URL은 접속하지 않음 - ---- +- Return ONLY the JSON object. Do NOT include any explanation, logging, or extra output. """ diff --git a/src/lib/llm/prompt/get_oauth/prompt.py b/src/lib/llm/prompt/get_oauth/prompt.py index 42685fd..4e4a698 100644 --- a/src/lib/llm/prompt/get_oauth/prompt.py +++ b/src/lib/llm/prompt/get_oauth/prompt.py @@ -24,7 +24,7 @@ Your task is to navigate to the login page of the given URL. Follow the steps be 2. SSO BUTTON IDENTIFICATION - On the login page, look for the following social login (SSO) buttons: - - Google, GitHub, Facebook, LinkedIn, Microsoft, Naver, Slack, Etc. + - Google, GitHub, Facebook, Microsoft, Naver, Etc. - ✅ Proceed only if it is clearly an **actual SSO button**. - ❌ Exclude the following: - Passkey-related buttons