Repository navigation
feat(web): 种子配置默认锁定 + 空 TZ 跟随 SOCKS5(#612 拆分) #613
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 |
|---|---|---|
|
|
@@ -3575,6 +3575,57 @@ export function createPanelHandler(ctx) { | |
| const next = defaultSeedPolicy(merged) | ||
| if (body.settings_json_override !== undefined) next.settings_json_override = body.settings_json_override | ||
| if (body.extra_env !== undefined) next.extra_env = body.extra_env || {} | ||
| const followProxyTz = body?.timezone_follow_proxy === true || body?.timezoneFollowProxy === true | ||
| const hasTimezone = body && Object.prototype.hasOwnProperty.call(body, 'timezone') | ||
| const hasLocale = body && Object.prototype.hasOwnProperty.call(body, 'locale') | ||
| let nextLocale = null | ||
| if (hasLocale) { | ||
| const requestedLocale = body.locale == null || body.locale === '' ? STANDARD_LOCALE : String(body.locale) | ||
| if (!SLOT_LOCALES.includes(requestedLocale)) { | ||
| return json(res, 400, { | ||
| ok: false, | ||
| error: { code: 'invalid_locale', message: `语言必须是 ${SLOT_LOCALES.join('、')}` }, | ||
| }) | ||
| } | ||
| nextLocale = requestedLocale | ||
| } | ||
| if (hasTimezone) { | ||
| const zone = validTimezone(body.timezone) | ||
| if (!zone) { | ||
| return json(res, 400, { | ||
| ok: false, | ||
| error: { | ||
| type: 'invalid_request_error', | ||
| code: 'invalid_timezone', | ||
| message: '时区必须是有效的 IANA 名称,如 Asia/Tokyo', | ||
| param: 'timezone', | ||
| }, | ||
| }) | ||
| } | ||
| const pinned = persistVmTimezone(cfg.paths.project, id, zone, { source: 'manual' }) | ||
| if (!pinned) return json(res, 404, { ok: false, error: { message: 'vm not found' } }) | ||
| Object.assign(vm, pinned) | ||
| } else if (followProxyTz) { | ||
| const synced = await syncVmTimezoneFromProxy(cfg.paths.project, proxyPool, id, { force: true }) | ||
| if (!synced.ok) { | ||
| return json(res, 400, { | ||
| ok: false, | ||
| error: { | ||
| type: 'invalid_request_error', | ||
| code: synced.reason || 'proxy_timezone_unknown', | ||
| message: '未能从代理节点取到时区,请先检测代理地理位置', | ||
| }, | ||
| }) | ||
| } | ||
| if (synced.applied) { | ||
| const fresh = getVm(cfg.paths.project, id) | ||
| if (fresh) Object.assign(vm, fresh) | ||
| } else if (synced.timezone) { | ||
| vm.timezone = synced.timezone | ||
| vm.timezone_source = 'proxy_geo' | ||
| } | ||
| } | ||
| if (nextLocale) vm.locale = nextLocale | ||
|
Contributor
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. Locale seed skips fingerprint localeMedium Severity Seed Reviewed by Cursor Bugbot for commit 6e055dc. Configure here. |
||
| vm.seed_policy = next | ||
| vm.updated_at = new Date().toISOString() | ||
| atomicWriteJson(vmPath, vm, { mode: 0o600 }) | ||
|
|
||


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.
Seed pin overwrites live VM record
High Severity
Pinning a timezone on seed
PUTassignspersistVmTimezone'ssummarizeVmresult onto the full slot record and writes that back. The summary redactsproxy.passwordto***and injects panel-only fields, so a seed that pins TZ can wipe the SOCKS password and pollutevms/<id>.json.Reviewed by Cursor Bugbot for commit 6e055dc. Configure here.