Spaces:
Paused
Paused
fix: restore required setup fields
Browse files- require CPA_URL and API_KEY again in setup checks while keeping proxy fields optional\n- default CPA_URL and auto-generate API_KEY when saving setup config\n- remove the host.docker.internal host-gateway mapping from default compose/docs
- docker-compose.yml +0 -2
- docs/configuration.md +2 -2
- docs/getting-started.md +1 -6
- docs/troubleshooting.md +1 -6
- src/autoteam/api.py +4 -1
- src/autoteam/setup_wizard.py +2 -2
- tests/unit/test_api_status.py +35 -0
- tests/unit/test_setup_wizard.py +2 -2
docker-compose.yml
CHANGED
|
@@ -1,8 +1,6 @@
|
|
| 1 |
services:
|
| 2 |
autoteam:
|
| 3 |
build: .
|
| 4 |
-
extra_hosts:
|
| 5 |
-
- "host.docker.internal:host-gateway"
|
| 6 |
ports:
|
| 7 |
- "8787:8787"
|
| 8 |
volumes:
|
|
|
|
| 1 |
services:
|
| 2 |
autoteam:
|
| 3 |
build: .
|
|
|
|
|
|
|
| 4 |
ports:
|
| 5 |
- "8787:8787"
|
| 6 |
volumes:
|
docs/configuration.md
CHANGED
|
@@ -14,9 +14,9 @@ cp .env.example .env
|
|
| 14 |
| `CLOUDMAIL_EMAIL` | CloudMail 登录邮箱 | 是 |
|
| 15 |
| `CLOUDMAIL_PASSWORD` | CloudMail 登录密码 | 是 |
|
| 16 |
| `CLOUDMAIL_DOMAIN` | 临时邮箱域名(如 `@example.com`) | 是 |
|
| 17 |
-
| `CPA_URL` | CLIProxyAPI 地址 |
|
| 18 |
| `CPA_KEY` | CPA 管理密钥 | 是 |
|
| 19 |
-
| `API_KEY` | Web 面板 / API 鉴权密钥 |
|
| 20 |
| `PLAYWRIGHT_PROXY_URL` | Playwright 浏览器代理 URL,如 `socks5://user:pass@host:port` | 否 |
|
| 21 |
| `PLAYWRIGHT_PROXY_BYPASS` | Playwright 代理绕过列表,如 `localhost,127.0.0.1` | 否 |
|
| 22 |
| `AUTO_CHECK_THRESHOLD` | 额度低于此百分比触发轮转 | 否(默认 `10`) |
|
|
|
|
| 14 |
| `CLOUDMAIL_EMAIL` | CloudMail 登录邮箱 | 是 |
|
| 15 |
| `CLOUDMAIL_PASSWORD` | CloudMail 登录密码 | 是 |
|
| 16 |
| `CLOUDMAIL_DOMAIN` | 临时邮箱域名(如 `@example.com`) | 是 |
|
| 17 |
+
| `CPA_URL` | CLIProxyAPI 地址 | 是(留空使用默认 `http://127.0.0.1:8317`) |
|
| 18 |
| `CPA_KEY` | CPA 管理密钥 | 是 |
|
| 19 |
+
| `API_KEY` | Web 面板 / API 鉴权密钥 | 是(首次启动可自动生成) |
|
| 20 |
| `PLAYWRIGHT_PROXY_URL` | Playwright 浏览器代理 URL,如 `socks5://user:pass@host:port` | 否 |
|
| 21 |
| `PLAYWRIGHT_PROXY_BYPASS` | Playwright 代理绕过列表,如 `localhost,127.0.0.1` | 否 |
|
| 22 |
| `AUTO_CHECK_THRESHOLD` | 额度低于此百分比触发轮转 | 否(默认 `10`) |
|
docs/getting-started.md
CHANGED
|
@@ -118,12 +118,7 @@ docker compose restart
|
|
| 118 |
|
| 119 |
直接打开 `http://your-server:8787`,会显示配置向导页面,在浏览器中填写。
|
| 120 |
|
| 121 |
-
如果你需要让浏览器流量走宿主机 SOCKS5 代理,
|
| 122 |
-
|
| 123 |
-
```yaml
|
| 124 |
-
extra_hosts:
|
| 125 |
-
- "host.docker.internal:host-gateway"
|
| 126 |
-
```
|
| 127 |
|
| 128 |
然后在 `data/.env` 中加入:
|
| 129 |
|
|
|
|
| 118 |
|
| 119 |
直接打开 `http://your-server:8787`,会显示配置向导页面,在浏览器中填写。
|
| 120 |
|
| 121 |
+
如果你需要让浏览器流量走宿主机 SOCKS5 代理,请先确认容器内可以解析并访问宿主机代理地址(例如 `host.docker.internal`,或你自己提供的宿主机网关别名)。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
|
| 123 |
然后在 `data/.env` 中加入:
|
| 124 |
|
docs/troubleshooting.md
CHANGED
|
@@ -170,12 +170,7 @@ volumes:
|
|
| 170 |
|
| 171 |
### 容器里访问不到宿主机 SOCKS5 代理
|
| 172 |
|
| 173 |
-
如果代理在宿主机上,比如 `host.docker.internal:1080`,
|
| 174 |
-
|
| 175 |
-
```yaml
|
| 176 |
-
extra_hosts:
|
| 177 |
-
- "host.docker.internal:host-gateway"
|
| 178 |
-
```
|
| 179 |
|
| 180 |
然后在 `data/.env` 中配置:
|
| 181 |
|
|
|
|
| 170 |
|
| 171 |
### 容器里访问不到宿主机 SOCKS5 代理
|
| 172 |
|
| 173 |
+
如果代理在宿主机上,比如 `host.docker.internal:1080`,请先确认容器内可以解析并访问宿主机代理地址;不同 Docker / Podman 环境的宿主机别名配置方式可能不同。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
|
| 175 |
然后在 `data/.env` 中配置:
|
| 176 |
|
src/autoteam/api.py
CHANGED
|
@@ -101,9 +101,12 @@ def post_setup_save(config: SetupConfig):
|
|
| 101 |
"""保存配置到 .env 并验证连通性"""
|
| 102 |
import secrets as _secrets
|
| 103 |
|
| 104 |
-
from autoteam.setup_wizard import _write_env
|
| 105 |
|
| 106 |
data = config.model_dump()
|
|
|
|
|
|
|
|
|
|
| 107 |
if not data.get("API_KEY"):
|
| 108 |
data["API_KEY"] = _secrets.token_urlsafe(24)
|
| 109 |
|
|
|
|
| 101 |
"""保存配置到 .env 并验证连通性"""
|
| 102 |
import secrets as _secrets
|
| 103 |
|
| 104 |
+
from autoteam.setup_wizard import REQUIRED_CONFIGS, _write_env
|
| 105 |
|
| 106 |
data = config.model_dump()
|
| 107 |
+
defaults = {key: default for key, _prompt, default, _optional in REQUIRED_CONFIGS}
|
| 108 |
+
if not data.get("CPA_URL"):
|
| 109 |
+
data["CPA_URL"] = defaults.get("CPA_URL", "http://127.0.0.1:8317")
|
| 110 |
if not data.get("API_KEY"):
|
| 111 |
data["API_KEY"] = _secrets.token_urlsafe(24)
|
| 112 |
|
src/autoteam/setup_wizard.py
CHANGED
|
@@ -20,11 +20,11 @@ REQUIRED_CONFIGS = [
|
|
| 20 |
("CLOUDMAIL_EMAIL", "CloudMail 登录邮箱", "", False),
|
| 21 |
("CLOUDMAIL_PASSWORD", "CloudMail 登录密码", "", False),
|
| 22 |
("CLOUDMAIL_DOMAIN", "CloudMail 邮箱域名(如 @example.com)", "", False),
|
| 23 |
-
("CPA_URL", "CPA (CLIProxyAPI) 地址", "http://127.0.0.1:8317",
|
| 24 |
("CPA_KEY", "CPA 管理密钥", "", False),
|
| 25 |
("PLAYWRIGHT_PROXY_URL", "Playwright 浏览器代理 URL(可选,如 socks5://host:port)", "", True),
|
| 26 |
("PLAYWRIGHT_PROXY_BYPASS", "Playwright 代理绕过列表(可选,如 localhost,127.0.0.1)", "", True),
|
| 27 |
-
("API_KEY", "API 鉴权密钥(回车自动生成)", "",
|
| 28 |
]
|
| 29 |
|
| 30 |
|
|
|
|
| 20 |
("CLOUDMAIL_EMAIL", "CloudMail 登录邮箱", "", False),
|
| 21 |
("CLOUDMAIL_PASSWORD", "CloudMail 登录密码", "", False),
|
| 22 |
("CLOUDMAIL_DOMAIN", "CloudMail 邮箱域名(如 @example.com)", "", False),
|
| 23 |
+
("CPA_URL", "CPA (CLIProxyAPI) 地址", "http://127.0.0.1:8317", False),
|
| 24 |
("CPA_KEY", "CPA 管理密钥", "", False),
|
| 25 |
("PLAYWRIGHT_PROXY_URL", "Playwright 浏览器代理 URL(可选,如 socks5://host:port)", "", True),
|
| 26 |
("PLAYWRIGHT_PROXY_BYPASS", "Playwright 代理绕过列表(可选,如 localhost,127.0.0.1)", "", True),
|
| 27 |
+
("API_KEY", "API 鉴权密钥(回车自动生成)", "", False),
|
| 28 |
]
|
| 29 |
|
| 30 |
|
tests/unit/test_api_status.py
CHANGED
|
@@ -67,3 +67,38 @@ def test_sanitize_account_keeps_exportable_main_account_active_without_live_quot
|
|
| 67 |
|
| 68 |
assert sanitized["is_main_account"] is True
|
| 69 |
assert sanitized["status"] == "active"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
assert sanitized["is_main_account"] is True
|
| 69 |
assert sanitized["status"] == "active"
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def test_post_setup_save_keeps_cpa_url_required_and_generates_api_key(monkeypatch):
|
| 73 |
+
written = {}
|
| 74 |
+
|
| 75 |
+
def fake_write_env(key, value):
|
| 76 |
+
written[key] = value
|
| 77 |
+
|
| 78 |
+
monkeypatch.setattr("autoteam.setup_wizard._write_env", fake_write_env)
|
| 79 |
+
monkeypatch.setattr("autoteam.setup_wizard._verify_cloudmail", lambda: True)
|
| 80 |
+
monkeypatch.setattr("autoteam.setup_wizard._verify_cpa", lambda: True)
|
| 81 |
+
monkeypatch.setattr("secrets.token_urlsafe", lambda _n: "generated-token")
|
| 82 |
+
monkeypatch.setattr("importlib.reload", lambda module: module)
|
| 83 |
+
monkeypatch.setattr(api, "API_KEY", "")
|
| 84 |
+
monkeypatch.delenv("CPA_URL", raising=False)
|
| 85 |
+
monkeypatch.delenv("API_KEY", raising=False)
|
| 86 |
+
|
| 87 |
+
result = api.post_setup_save(
|
| 88 |
+
api.SetupConfig(
|
| 89 |
+
CLOUDMAIL_BASE_URL="http://mail.example.com",
|
| 90 |
+
CLOUDMAIL_EMAIL="admin@example.com",
|
| 91 |
+
CLOUDMAIL_PASSWORD="secret",
|
| 92 |
+
CLOUDMAIL_DOMAIN="@example.com",
|
| 93 |
+
CPA_URL="",
|
| 94 |
+
CPA_KEY="key-1",
|
| 95 |
+
PLAYWRIGHT_PROXY_URL="",
|
| 96 |
+
PLAYWRIGHT_PROXY_BYPASS="",
|
| 97 |
+
API_KEY="",
|
| 98 |
+
)
|
| 99 |
+
)
|
| 100 |
+
|
| 101 |
+
assert written["CPA_URL"] == "http://127.0.0.1:8317"
|
| 102 |
+
assert written["API_KEY"] == "generated-token"
|
| 103 |
+
assert result["api_key"] == "generated-token"
|
| 104 |
+
assert api.API_KEY == "generated-token"
|
tests/unit/test_setup_wizard.py
CHANGED
|
@@ -81,8 +81,8 @@ def test_check_and_setup_non_interactive_reports_missing_required_fields(tmp_pat
|
|
| 81 |
assert ok is False
|
| 82 |
assert "[配置] 缺少必填项: CLOUDMAIL_BASE_URL" in caplog.text
|
| 83 |
assert "[配置] 缺少必填项: CPA_KEY" in caplog.text
|
| 84 |
-
assert "[配置] 缺少必填项: CPA_URL"
|
| 85 |
assert "[配置] 缺少必填项: PLAYWRIGHT_PROXY_URL" not in caplog.text
|
| 86 |
assert "[配置] 缺少必填项: PLAYWRIGHT_PROXY_BYPASS" not in caplog.text
|
| 87 |
-
assert "[配置] 缺少必填项: API_KEY"
|
| 88 |
assert "[配置] 请通过 Web 面板或编辑 .env 文件填入配置" in caplog.text
|
|
|
|
| 81 |
assert ok is False
|
| 82 |
assert "[配置] 缺少必填项: CLOUDMAIL_BASE_URL" in caplog.text
|
| 83 |
assert "[配置] 缺少必填项: CPA_KEY" in caplog.text
|
| 84 |
+
assert "[配置] 缺少必填项: CPA_URL" in caplog.text
|
| 85 |
assert "[配置] 缺少必填项: PLAYWRIGHT_PROXY_URL" not in caplog.text
|
| 86 |
assert "[配置] 缺少必填项: PLAYWRIGHT_PROXY_BYPASS" not in caplog.text
|
| 87 |
+
assert "[配置] 缺少必填项: API_KEY" in caplog.text
|
| 88 |
assert "[配置] 请通过 Web 面板或编辑 .env 文件填入配置" in caplog.text
|