This commit is contained in:
Your Name
2026-09-01 15:31:05 +08:00
parent 1f3addcf79
commit 2fc864cc00
20 changed files with 1381 additions and 45 deletions
+34 -3
View File
@@ -84,6 +84,7 @@ from rpa_engine.credential import (
assess_account_credential,
build_im_session_from_storage,
build_cookie_credential_detail,
credential_egress_mismatch,
)
from utils.cookie_store import (
write_cookie_file,
@@ -1864,6 +1865,7 @@ async def update_account(
if body.user_agent is not None:
ua = (body.user_agent or "").strip()
account.user_agent = ua or None
egress_changed = False
if "egress_public_ip" in body.model_fields_set:
selected_public_ip = str(body.egress_public_ip or "").strip()
if selected_public_ip:
@@ -1873,12 +1875,27 @@ async def update_account(
raise HTTPException(status_code=400, detail="公网通道必须是有效的 IPv4 地址")
if parsed_ip.version != 4:
raise HTTPException(status_code=400, detail="公网通道目前仅支持 IPv4")
previous_public_ip = str(account.egress_public_ip or "").strip()
egress_changed = previous_public_ip != selected_public_ip
account.egress_public_ip = selected_public_ip or None
if body.egress_auto_attempts is not None:
account.egress_auto_attempts = clamp_attempts(body.egress_auto_attempts)
account.updated_at = datetime.utcnow()
await db.commit()
await db.refresh(account)
if egress_changed and manager.is_running(account_id):
await manager.stop_worker(account_id)
await db.execute(
update(Account).where(Account.id == account_id).values(
status="offline",
error_message=(
"公网通道已变更,请重新启动托管以使用新通道;"
"已保留登录凭证,校验通过后无需重新扫码"
),
)
)
await db.commit()
await db.refresh(account)
if follow_config_changed:
worker = manager.workers.get(account_id)
invalidate = getattr(worker, "invalidate_follow_welcome_config", None)
@@ -1888,8 +1905,9 @@ async def update_account(
runtime_service = getattr(worker, "_im_service", None) if worker else None
if runtime_service:
runtime_session = runtime_service.session
runtime_session.egress_public_ip = str(account.egress_public_ip or "").strip()
runtime_session.egress_source_ip = ""
# Reconnect after a public-IP change so HTTP and the existing WS do
# not use different routes. Reconnecting does not invalidate cookies.
# Only the retry-count can be hot-updated without reconnecting.
runtime_session.egress_auto_attempts = clamp_attempts(account.egress_auto_attempts)
return _build_account_response(account)
@@ -2350,13 +2368,26 @@ async def _start_account_rpa_impl(
# Credential assessment issues real network requests to Douyin, and a bulk
# start runs it for every queued account. Release the connection first.
await _release_db_connection(db)
reset_performed = False
selected_public_ip = str(getattr(account, "egress_public_ip", "") or "").strip()
if credential_egress_mismatch(cookie_data, selected_public_ip):
# The stored IP is local metadata, not a platform authentication
# verdict. Imported/legacy cookies may not have it at all. Keep the
# credentials and use normal validation on the selected route.
logger.info(
"Account %s egress marker differs; preserving credentials and "
"validating on selected channel %s",
account_id,
selected_public_ip or "default",
)
assessment = await assess_account_credential(
cookie_data,
account.im_session_data,
startup_priority=True,
egress_public_ip=selected_public_ip,
)
login_mode = requested_login_mode or assessment["login_mode"]
reset_performed = False
if assessment.get("should_reset") and login_mode != "im_direct":
account = await _reset_account_credentials(account_id, db)