设置页重做:配置文件下载上传、内核参数、资源、免责声明
配置每次落盘都打顶层 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:
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* 配置文件里的 Patchbay 标记。
|
||||
*
|
||||
* 每次落盘都在顶层写一个 `patchbay:` 键(内核对未知顶层键不报错:解析用的
|
||||
* `yaml.Unmarshal` 没开严格模式,config/config.go:612)。上传配置文件时靠它
|
||||
* 区分「Patchbay 管理过的配置」和随便一份 mihomo 配置——前者直接还原,
|
||||
* 后者提示走导入。
|
||||
*
|
||||
* sig 是盐加版本号的哈希,回答的是「这个标记是不是 Patchbay 写的」,不是防伪
|
||||
* ——在用户自己的机器上没有对手。刻意不对配置内容做哈希:这个项目只接管部分
|
||||
* 段落,手改其余段落是正常用法(决策记录 0003),内容哈希会把合法的手改
|
||||
* 判成无效。
|
||||
*/
|
||||
import type { ConfigObject } from '../vendor/config-editor/index.ts'
|
||||
|
||||
export const MARKER_KEY = 'patchbay'
|
||||
|
||||
const VERSION = 1
|
||||
const SALT = 'patchbay-config-salt'
|
||||
|
||||
/** FNV-1a。只做标记指纹,不是安全用途。 */
|
||||
function fnv(text: string): string {
|
||||
let h = 0x811c9dc5
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
h ^= text.charCodeAt(i)
|
||||
h = Math.imul(h, 0x01000193)
|
||||
}
|
||||
return (h >>> 0).toString(16).padStart(8, '0')
|
||||
}
|
||||
|
||||
const sigOf = (version: number): string => fnv(`${SALT}:${String(version)}`)
|
||||
|
||||
/** 给一份配置打上标记。已有的旧标记会被换成当前版本的。 */
|
||||
export function withMarker(data: ConfigObject): ConfigObject {
|
||||
return { ...data, [MARKER_KEY]: { v: VERSION, sig: sigOf(VERSION) } }
|
||||
}
|
||||
|
||||
/** 这份配置带不带有效的 Patchbay 标记。 */
|
||||
export function hasValidMarker(data: ConfigObject): boolean {
|
||||
const marker = data[MARKER_KEY]
|
||||
if (typeof marker !== 'object' || marker === null || Array.isArray(marker)) return false
|
||||
const { v, sig } = marker as Record<string, unknown>
|
||||
return typeof v === 'number' && sig === sigOf(v)
|
||||
}
|
||||
Reference in New Issue
Block a user