Remove server remote browser support
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
"""Auth credential extraction from remote browser sessions."""
|
||||
"""Credential candidate curation for real-browser auth imports."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
@@ -23,116 +23,6 @@ SESSION_COOKIE_NAMES = frozenset({
|
||||
})
|
||||
|
||||
|
||||
async def extract_cookies(session: Any) -> list[dict[str, Any]]:
|
||||
"""Extract all cookies from the browser context."""
|
||||
cookies = await session.context.cookies()
|
||||
return [
|
||||
{
|
||||
"name": c.get("name", ""),
|
||||
"value": c.get("value", ""),
|
||||
"domain": c.get("domain", ""),
|
||||
"httpOnly": c.get("httpOnly", False),
|
||||
"secure": c.get("secure", False),
|
||||
}
|
||||
for c in cookies
|
||||
]
|
||||
|
||||
|
||||
async def extract_local_storage(page: Any) -> dict[str, str]:
|
||||
try:
|
||||
raw = await page.evaluate("() => JSON.stringify(window.localStorage)")
|
||||
if isinstance(raw, str):
|
||||
return json.loads(raw)
|
||||
return raw or {}
|
||||
except Exception as exc:
|
||||
logger.debug("localStorage extraction failed: %s", exc)
|
||||
return {}
|
||||
|
||||
|
||||
async def extract_session_storage(page: Any) -> dict[str, str]:
|
||||
try:
|
||||
raw = await page.evaluate("() => JSON.stringify(window.sessionStorage)")
|
||||
if isinstance(raw, str):
|
||||
return json.loads(raw)
|
||||
return raw or {}
|
||||
except Exception as exc:
|
||||
logger.debug("sessionStorage extraction failed: %s", exc)
|
||||
return {}
|
||||
|
||||
|
||||
async def extract_new_api_user_id(page: Any) -> str:
|
||||
try:
|
||||
value = await page.evaluate("""
|
||||
async () => {
|
||||
const uid = localStorage.getItem('uid')
|
||||
if (uid) return uid
|
||||
const userRaw = localStorage.getItem('user')
|
||||
if (userRaw) {
|
||||
try {
|
||||
const user = JSON.parse(userRaw)
|
||||
if (user?.id) return String(user.id)
|
||||
} catch {}
|
||||
}
|
||||
const response = await fetch('/api/user/self', { credentials: 'include' })
|
||||
if (!response.ok) return ''
|
||||
const payload = await response.json()
|
||||
const data = payload?.data || payload
|
||||
return data?.id ? String(data.id) : ''
|
||||
}
|
||||
""")
|
||||
return str(value or "").strip()
|
||||
except Exception as exc:
|
||||
logger.debug("New-API user id extraction failed: %s", exc)
|
||||
return ""
|
||||
|
||||
|
||||
async def extract_request_headers(session: Any) -> list[dict[str, str]]:
|
||||
"""Return Authorization / API-Key headers captured continuously by CDP.
|
||||
|
||||
The CDP Network listener is started when the ephemeral session is created
|
||||
(in BrowserSessionService.create_ephemeral), so headers from the login
|
||||
flow are captured in real-time without needing a fresh CDP attach.
|
||||
"""
|
||||
if hasattr(session, "captured_headers") and session.captured_headers:
|
||||
logger.debug("auth-capture: returning %d cached headers", len(session.captured_headers))
|
||||
return list(session.captured_headers)
|
||||
return []
|
||||
|
||||
|
||||
async def extract_all(session: Any) -> dict[str, Any]:
|
||||
"""Extract all auth credentials from a browser session.
|
||||
|
||||
Returns:
|
||||
cookies, storage, session_storage, auth_headers, candidates
|
||||
"""
|
||||
page = session.page
|
||||
cookies = await extract_cookies(session)
|
||||
local_storage = await extract_local_storage(page)
|
||||
session_storage = await extract_session_storage(page)
|
||||
auth_headers = await extract_request_headers(session)
|
||||
new_api_user = _find_new_api_user(local_storage, session_storage) or await extract_new_api_user_id(page)
|
||||
|
||||
# 获取当前浏览器页面的真实 URL(比 session.url 更准确)
|
||||
page_url = ""
|
||||
try:
|
||||
page_url = page.url or ""
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
candidates = _curate_candidates(
|
||||
cookies, local_storage, session_storage, auth_headers, new_api_user,
|
||||
page_url=page_url,
|
||||
)
|
||||
|
||||
return {
|
||||
"cookies": cookies,
|
||||
"storage": local_storage,
|
||||
"session_storage": session_storage,
|
||||
"auth_headers": auth_headers,
|
||||
"candidates": candidates,
|
||||
}
|
||||
|
||||
|
||||
def _cookie_matches_hostname(cookie_domain: str, hostname: str) -> bool:
|
||||
"""判断 cookie domain 是否适用于给定 hostname。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user