mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/mihomo-party-org/clash-party.git
synced 2026-09-20 08:03:39 +08:00
Client-side hardening of the CPX airport plugin, squashed from 46 commits
forked at 89c2bb0e. Behaviour changes:
- Unified operation model (§0.4/0.5): one deadline + one AbortSignal + one
persistence commit per operation; per-plugin lock → vault lock hierarchy;
tombstone on delete; every wait (lock, DNS preflight, proxy resolution,
vault decrypt) is bounded by the same budget.
- Routing: direct/proxy auto-fallback with a pre-send guard; proxied https
builds its own CONNECT tunnel (an aborted hung CONNECT closes its socket);
invalid local-proxy ports are refused instead of falling back to :80; the
core's inbound credentials are carried to the local proxy; NAT64 and
site-local IPv6 ranges are non-public.
- Gateways: multi-gateway recovery with one rediscovery per operation,
normalized endpoint paths, signed discovery documents (Ed25519, seq/digest
accept/align/rollback/equivocation), commit order vault → plugin.yaml.
- Subscriptions: a fetched subscription is validated by the core (mihomo -t)
against the current override set before it replaces the profile, inside
the profile write critical section (profile.yaml and override.yaml share
one write queue); schedule fields are read at write time; the first
subscription is activated through the real switch flow; profile deletion
removes the record last so any failure stays retryable.
- Devices: a re-login that replaces a still-valid device records it in the
vault (staleDevices) and retires it after the login, after later
successful fetches and on removal; enroll compensation restores the old
vault and keeps an un-revoked new device for retirement.
- Vault: on Linux the vault is persisted only behind a system secret store
(backend name + ciphertext-prefix canary); otherwise it stays in memory.
A cache-miss read releases the caller at the budget while the lock is held
until the decrypt ends.
- Config caches (plugin.yaml, profile.yaml, override.yaml) can no longer be
rolled back by a late cold read.
- Reference gateway and provider guides updated (deploy contract, discoveryUrls
same-origin rule, /revoke after re-login); https-proxy-agent dropped.
Reviewed in a Codex loop (gpt-6, 38 calls): 74 findings, 68 fixed and
verified, 6 invalid, no backlog. Tests: vitest 501, gateway 106.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
31 lines
1.1 KiB
JavaScript
Executable File
31 lines
1.1 KiB
JavaScript
Executable File
#!/usr/bin/env -S node --experimental-sqlite --disable-warning=ExperimentalWarning
|
|
// cpx-admin CLI entrypoint. Wires the real account DB + a no-echo password reader into
|
|
// the tested command logic (src/admin.mjs). The offline signing commands (keygen,
|
|
// sign-discovery) never touch the database, so it is only opened for the others.
|
|
import { readFileSync, writeFileSync } from 'node:fs'
|
|
import { loadConfig } from './src/config.mjs'
|
|
import { runAdmin } from './src/admin.mjs'
|
|
import { readPassword } from './src/prompt.mjs'
|
|
|
|
const OFFLINE_COMMANDS = new Set(['keygen', 'sign-discovery'])
|
|
|
|
const config = loadConfig()
|
|
const args = process.argv.slice(2)
|
|
let db
|
|
if (!OFFLINE_COMMANDS.has(args[0])) {
|
|
const { openDb } = await import('./src/db.mjs')
|
|
db = openDb(config.dbPath)
|
|
}
|
|
const code = await runAdmin(args, {
|
|
db,
|
|
deviceLimitDefault: config.deviceLimitDefault,
|
|
readPassword,
|
|
readFile: (p) => readFileSync(p, 'utf-8'),
|
|
writeFile: (p, data, opts) => writeFileSync(p, data, opts),
|
|
readStdin: async () => readFileSync(0, 'utf-8'),
|
|
out: (s) => console.log(s),
|
|
err: (s) => console.error(s)
|
|
})
|
|
db?.close()
|
|
process.exit(code)
|