设置页重做:配置文件下载上传、内核参数、资源、免责声明
配置每次落盘都打顶层 patchbay: 标记(盐加版本的哈希)。内核忽略未知 顶层键(yaml.Unmarshal 没开严格模式,config/config.go:612)。刻意不对 内容做哈希:本项目只接管部分段落,手改其余段落是正常用法,内容哈希 会把合法手改判成无效。上传配置时靠标记分流:有标记的确认后替换, 没有的用更重的措辞确认导入;两者都走 config-store 完整保护链路 (新端点 POST /api/config/import)。自动备份列表从界面撤下,改成 下载当前配置 + 拖放上传。 内核参数一组编辑五个老式顶层端口和 keep-alive-interval(config.go:444, 整数秒),走带基准指纹的保存链路。资源一组接 POST /configs/geo (同步接口,透传给了 300 秒超时)。测速地址成为本地偏好,延迟测试 读它;prefs 模块顶层的浏览器全局加了存在性守卫——api.ts 开始引用 prefs,而 bun test 环境没有 localStorage。 退出登录挪到侧栏底部;密度设置从设置页撤下(侧栏按钮还在); 免责声明和关于做成子页(左上角返回),登录页输入框下加同一份 免责声明的弹层入口。
This commit is contained in:
+30
-4
@@ -7,12 +7,10 @@
|
||||
import type { ConfigDiagnostic, ConfigObject } from '../vendor/config-editor/index.ts'
|
||||
import type { ConnectionSnapshot } from '@shared/connections.ts'
|
||||
import type { ExitProbe, HostInfo } from '@shared/host-info.ts'
|
||||
import { DEFAULT_TEST_URL, testUrl } from './prefs'
|
||||
|
||||
const TOKEN_KEY = 'patchbay.token'
|
||||
|
||||
/** 测延迟用的目标。204 空响应,体积最小,全球都有部署。 */
|
||||
const TEST_URL = 'https://www.gstatic.com/generate_204'
|
||||
|
||||
export function getToken(): string {
|
||||
return localStorage.getItem(TOKEN_KEY) ?? ''
|
||||
}
|
||||
@@ -144,6 +142,26 @@ export const api = {
|
||||
|
||||
listBackups: () => request<{ backups: string[] }>('GET', '/api/config/backups'),
|
||||
|
||||
/** 配置文件的原文,给「下载当前配置」用。 */
|
||||
configRaw: async (): Promise<string> => {
|
||||
const res = await fetch('/api/config/raw', {
|
||||
headers: { Authorization: `Bearer ${getToken()}` },
|
||||
})
|
||||
if (!res.ok) {
|
||||
const text = await res.text()
|
||||
const payload = text ? (JSON.parse(text) as Record<string, unknown>) : {}
|
||||
throw new ApiError(res.status, payload)
|
||||
}
|
||||
return res.text()
|
||||
},
|
||||
|
||||
/**
|
||||
* 用上传的 YAML 原文整份替换当前配置。走服务端完整的保护链路
|
||||
* (校验、备份、重载、失败回退),没有 baseRevision——整份替换本来就是覆盖语义。
|
||||
*/
|
||||
importConfig: (content: string) =>
|
||||
request<ApplySuccess>('POST', '/api/config/import', { content }),
|
||||
|
||||
restoreBackup: (name: string) =>
|
||||
request<ApplySuccess>('POST', `/api/config/backups/${encodeURIComponent(name)}/restore`),
|
||||
|
||||
@@ -170,6 +188,12 @@ export const api = {
|
||||
*/
|
||||
restartKernel: () => request<{ ok: true }>('POST', '/api/kernel/restart'),
|
||||
|
||||
/**
|
||||
* 让内核更新 GEO 数据库(GEOIP、GEOSITE、MMDB、ASN)。
|
||||
* 同步接口,下载完才回话,可能要等上几十秒。
|
||||
*/
|
||||
updateGeo: () => request<{ ok: true }>('POST', '/api/kernel/geo'),
|
||||
|
||||
/**
|
||||
* 打开一个持续吐数据的流式接口(/traffic、/memory),每秒一行 JSON。
|
||||
*
|
||||
@@ -222,7 +246,9 @@ export const api = {
|
||||
* 订阅线路不在表里(那正是它们无法被入站直接引用的原因),只能从所属订阅进去测。
|
||||
*/
|
||||
testLine: (name: string, provider?: string, timeout = 5000) => {
|
||||
const q = `url=${encodeURIComponent(TEST_URL)}&timeout=${String(timeout)}`
|
||||
// 测速地址是设置页里的偏好,空值退回默认
|
||||
const target = testUrl.value.trim() || DEFAULT_TEST_URL
|
||||
const q = `url=${encodeURIComponent(target)}&timeout=${String(timeout)}`
|
||||
const path = provider
|
||||
? `/api/kernel/providers/proxies/${encodeURIComponent(provider)}/${encodeURIComponent(name)}/healthcheck?${q}`
|
||||
: `/api/kernel/proxies/${encodeURIComponent(name)}/delay?${q}`
|
||||
|
||||
Reference in New Issue
Block a user