-
Notifications
You must be signed in to change notification settings - Fork 0
build: v1.6.1 #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,15 +3,19 @@ | |
| """Root Router - 认证和配置管理 API""" | ||
|
|
||
| import time | ||
| import httpx | ||
| from functools import wraps | ||
| from urllib.parse import urlsplit | ||
| from fastapi import APIRouter, HTTPException, Header | ||
| from fastapi.responses import JSONResponse | ||
| from pydantic import BaseModel | ||
| from typing import Optional | ||
|
|
||
| from infra import backend | ||
| from core.crypto import decrypt | ||
|
|
||
| root_router = APIRouter(prefix='/root') | ||
| api_config_router = APIRouter(prefix='/api') | ||
|
|
||
|
|
||
| # ===== 鉴权相关 ===== | ||
|
|
@@ -69,6 +73,12 @@ class WhitelistUpdate(BaseModel): | |
| whitelist: list[str] | ||
|
|
||
|
|
||
| class ApiConfigUpdate(BaseModel): | ||
| backendUrl: str | None = None | ||
| currentBackend: str | None = None | ||
| secret: str | None = None | ||
|
|
||
|
|
||
| @root_router.get("/") | ||
| async def root_status(): | ||
| return {"status": "ok", "has_secret": is_auth_required()} | ||
|
|
@@ -130,4 +140,43 @@ async def update_whitelist(req: WhitelistUpdate, x_secret: Optional[str] = Heade | |
| if is_auth_required() and not verify_secret(x_secret or ''): | ||
| raise HTTPException(401, "鉴权失败") | ||
| backend.config.set('root_whitelist', req.whitelist) | ||
| return {"success": True} | ||
| return {"success": True} | ||
|
|
||
|
|
||
| @api_config_router.get('/config') | ||
| async def get_api_config(): | ||
| return { | ||
| 'backendUrl': backend.config.get('frontend_backend_url'), | ||
| 'bgGif': None | ||
| } | ||
|
|
||
|
|
||
| @api_config_router.post('/config') | ||
| async def update_api_config(req: ApiConfigUpdate): | ||
| if not req.secret: | ||
| return JSONResponse({'error': '需要密钥'}, status_code=401) | ||
| if not is_auth_required(): | ||
| return JSONResponse({'error': '请先设置密钥'}, status_code=403) | ||
| if not verify_secret(req.secret): | ||
| return JSONResponse({'error': '密钥验证失败'}, status_code=401) | ||
|
|
||
| target = (req.backendUrl or '').strip().rstrip('/') | ||
|
Comment on lines
+154
to
+163
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): Authentication failures against the target backend are treated as connectivity failures, which can mislead users. The connectivity check currently treats any |
||
| if not target: | ||
| return JSONResponse({'error': '需要目标后端地址'}, status_code=400) | ||
| try: | ||
| parts = urlsplit(target) | ||
| except ValueError: | ||
| return JSONResponse({'error': '地址格式不正确'}, status_code=400) | ||
| if parts.scheme not in ('http', 'https') or not parts.netloc: | ||
| return JSONResponse({'error': '地址必须以 http:// 或 https:// 开头'}, status_code=400) | ||
|
|
||
| try: | ||
| async with httpx.AsyncClient(timeout=5.0) as client: | ||
| r = await client.get(f'{target}/root/') | ||
| if r.status_code >= 400: | ||
| return JSONResponse({'error': '无法连接目标后端'}, status_code=502) | ||
| except httpx.HTTPError: | ||
| return JSONResponse({'error': '无法连接目标后端'}, status_code=502) | ||
|
|
||
| backend.config.set('frontend_backend_url', target) | ||
| return {'success': True} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
|
|
||
| --- | ||
|
|
||
| [🚀快速开始](https://doc.redviewer.nyc.mn/deploy/) | [❓常见问题](https://doc.redviewer.nyc.mn/faq/) | ||
| [🚀快速开始](https://rv.101114105.xyz/deploy/) | [❓常见问题](https://rv.101114105.xyz/faq/) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,6 @@ | ||
|
|
||
| ## 🍢 Feat/Fix | ||
|
|
||
| ✨ 桌面应用,当前win(mac/linux很快就有 | ||
| + nyc.mn 旧域名已废弃,新域名后缀 xyz | ||
| + win安装自动开防火墙 | ||
| + 文档更新内容,例如个人更方便的 Tunnel 方案 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: The
currentBackendfield inApiConfigUpdateis defined but never used in the endpoint logic.Since only
backendUrlandsecretare read inupdate_api_config, consider removingcurrentBackendto keep the model minimal. If you plan to use it later, either wire it into the current logic now or introduce a dedicated DTO when that logic is added.Suggested implementation:
currentBackend(e.g. in request bodies, tests, or frontend code) and remove or adjust them accordingly.