Conversation
Reviewer's GuideAdds a global backend URL config API and frontend initialization logic, improves the page reader with first/last page controls, updates Windows installer firewall behavior and Tauri packaging, and refreshes docs/links to the new xyz domain and revised deployment guidance. Sequence diagram for backend URL initialization via api_configsequenceDiagram
actor User
participant Browser
participant Frontend_initBackend as Frontend_initBackend
participant LocalStorage
participant Backend_api as Backend_api_config
participant DesktopDetector
participant EnvConfig
User->>Browser: Load frontend app
Browser->>Frontend_initBackend: Call initBackend()
Frontend_initBackend->>LocalStorage: Get backendUrl
LocalStorage-->>Frontend_initBackend: localUrl or null
Frontend_initBackend->>LocalStorage: Get list_bg
LocalStorage-->>Frontend_initBackend: localBg or null
note over Frontend_initBackend: If localUrl exists, set _backendUrl
note over Frontend_initBackend: If localBg exists, set _listBg
Frontend_initBackend->>Backend_api: GET /api/config
alt Backend_api returns 200
Backend_api-->>Frontend_initBackend: { backendUrl, bgGif }
note over Frontend_initBackend: serverUrl = backendUrl
alt localUrl is null and backendUrl exists
Frontend_initBackend->>Frontend_initBackend: _backendUrl = backendUrl
end
alt localBg is null and bgGif exists
Frontend_initBackend->>Frontend_initBackend: _listBg = bgGif
end
else Backend_api error
Backend_api-->>Frontend_initBackend: error
Frontend_initBackend->>Frontend_initBackend: Log warning
end
alt no localUrl and no serverUrl
Frontend_initBackend->>DesktopDetector: detectDesktopBackendUrl()
DesktopDetector-->>Frontend_initBackend: desktopUrl or null
alt desktopUrl exists
Frontend_initBackend->>Frontend_initBackend: _backendUrl = desktopUrl
else
Frontend_initBackend->>EnvConfig: Read import.meta.env.LAN_IP
EnvConfig-->>Frontend_initBackend: fallbackUrl
Frontend_initBackend->>Frontend_initBackend: _backendUrl = fallbackUrl
end
end
Frontend_initBackend-->>Browser: Resolved _backendUrl
Sequence diagram for updating global backend URL via api_configsequenceDiagram
actor AdminUser
participant Browser
participant Frontend_TabBackend as Frontend_TabBackend
participant Backend_api as Backend_api_config
participant RootAuth as Root_auth
participant TargetBackend as Target_backend
participant ConfigStore
AdminUser->>Browser: Open root admin TabBackend
AdminUser->>Frontend_TabBackend: Enter backendUrl and secret
AdminUser->>Frontend_TabBackend: Click saveBackend()
Frontend_TabBackend->>Backend_api: POST /api/config { backendUrl, secret }
Backend_api->>RootAuth: is_auth_required()
RootAuth-->>Backend_api: auth_required flag
alt no secret provided
Backend_api-->>Frontend_TabBackend: 401 需要密钥
else secret provided but auth not configured
Backend_api-->>Frontend_TabBackend: 403 请先设置密钥
else secret provided and auth configured
Backend_api->>RootAuth: verify_secret(secret)
RootAuth-->>Backend_api: valid or invalid
alt secret invalid
Backend_api-->>Frontend_TabBackend: 401 密钥验证失败
else secret valid
Backend_api->>Backend_api: Normalize backendUrl (trim, strip '/')
alt backendUrl empty or invalid format
Backend_api-->>Frontend_TabBackend: 400 地址错误
else backendUrl valid
Backend_api->>TargetBackend: GET {backendUrl}/root/
alt TargetBackend reachable and status < 400
TargetBackend-->>Backend_api: 200 OK
Backend_api->>ConfigStore: set frontend_backend_url = backendUrl
ConfigStore-->>Backend_api: saved
Backend_api-->>Frontend_TabBackend: 200 success
else connection fails or status >= 400
TargetBackend-->>Backend_api: error
Backend_api-->>Frontend_TabBackend: 502 无法连接目标后端
end
end
end
end
alt globalSaved is true in frontend
Frontend_TabBackend->>Browser: localStorage.removeItem(backendUrl)
Frontend_TabBackend->>AdminUser: Show toast 全局配置已更新,所有设备刷新后生效
else globalSaved is false
Frontend_TabBackend->>Browser: localStorage.setItem(backendUrl)
Frontend_TabBackend->>AdminUser: Show local-only saved message
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- In
ApiConfigUpdatethecurrentBackendfield is never used inupdate_api_config; consider either wiring it into the logic (e.g., for validation or migration) or removing it to avoid confusion about its purpose. - In
update_api_configafter successfully settingfrontend_backend_urlyou don't return any explicit success payload, so clients will receive anullJSON body; consider returning a simple{ "success": true }(and possibly the saved URL) for clearer client handling and consistency with other endpoints.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `ApiConfigUpdate` the `currentBackend` field is never used in `update_api_config`; consider either wiring it into the logic (e.g., for validation or migration) or removing it to avoid confusion about its purpose.
- In `update_api_config` after successfully setting `frontend_backend_url` you don't return any explicit success payload, so clients will receive a `null` JSON body; consider returning a simple `{ "success": true }` (and possibly the saved URL) for clearer client handling and consistency with other endpoints.
## Individual Comments
### Comment 1
<location> `backend/api/routes/root.py:76-79` </location>
<code_context>
whitelist: list[str]
+class ApiConfigUpdate(BaseModel):
+ backendUrl: str | None = None
+ currentBackend: str | None = None
+ secret: str | None = None
+
+
</code_context>
<issue_to_address>
**suggestion:** The `currentBackend` field in `ApiConfigUpdate` is defined but never used in the endpoint logic.
Since only `backendUrl` and `secret` are read in `update_api_config`, consider removing `currentBackend` to 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:
```python
class ApiConfigUpdate(BaseModel):
backendUrl: str | None = None
secret: str | None = None
```
1. Search the codebase for any remaining references to `currentBackend` (e.g. in request bodies, tests, or frontend code) and remove or adjust them accordingly.
2. If this API is consumed externally, consider whether this is a breaking change; if so, update API documentation and any client DTOs to match.
</issue_to_address>
### Comment 2
<location> `backend/api/routes/root.py:154-163` </location>
<code_context>
+@api_config_router.post('/config')
</code_context>
<issue_to_address>
**issue (bug_risk):** Authentication failures against the target backend are treated as connectivity failures, which can mislead users.
The connectivity check currently treats any `r.status_code >= 400` as a network error and returns `"无法连接目标后端"`. For backends that require their own credentials, a 401/403 still proves the URL is reachable, but the message implies a connectivity problem instead of an auth issue. Consider either treating any HTTP response as a successful connectivity check and only handling transport-level failures, or special-casing 401/403 (and possibly other 4xx) with a more accurate error message to avoid confusing users for protected backends.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| class ApiConfigUpdate(BaseModel): | ||
| backendUrl: str | None = None | ||
| currentBackend: str | None = None | ||
| secret: str | None = None |
There was a problem hiding this comment.
suggestion: The currentBackend field in ApiConfigUpdate is defined but never used in the endpoint logic.
Since only backendUrl and secret are read in update_api_config, consider removing currentBackend to 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:
class ApiConfigUpdate(BaseModel):
backendUrl: str | None = None
secret: str | None = None- Search the codebase for any remaining references to
currentBackend(e.g. in request bodies, tests, or frontend code) and remove or adjust them accordingly. - If this API is consumed externally, consider whether this is a breaking change; if so, update API documentation and any client DTOs to match.
| @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('/') |
There was a problem hiding this comment.
issue (bug_risk): Authentication failures against the target backend are treated as connectivity failures, which can mislead users.
The connectivity check currently treats any r.status_code >= 400 as a network error and returns "无法连接目标后端". For backends that require their own credentials, a 401/403 still proves the URL is reachable, but the message implies a connectivity problem instead of an auth issue. Consider either treating any HTTP response as a successful connectivity check and only handling transport-level failures, or special-casing 401/403 (and possibly other 4xx) with a more accurate error message to avoid confusing users for protected backends.
Summary by Sourcery
Update viewer navigation, backend configuration, domains, and installer behavior for the v1.6.1 release.
New Features:
Bug Fixes:
Enhancements:
Build:
Documentation: