Commit Graph
47 Commits
Author SHA1 Message Date
Z User fbca88a534 fix(config): align listener/client fields with MetaCubeX wiki (round 2)
Complete field-level audit against https://wiki.metacubex.one/ for 8 protocols
(shadowsocks/vmess/vless/trojan/hysteria2/tuic-v4/tuic-v5/sudoku).
HIGH (8):
- VLESS listener: strip client-only `encryption` field (server uses `decryption`)
- mux-option: drop undocumented `brutal-opts` from all 9 listener schemas (keep `brutal` map)
- vmess/vless/trojan listener: drop fabricated top-level `ws-headers` (client uses ws-opts.headers)
- 3m-ui share: nest ws-opts.Host under headers map per proxies-transport
- hysteria2 listener: drop `handshake-timeout`/`max-idle-time` (client/TUIC only)
- m-ui hysteria2Listener: drop 6 quic-go fields (cwnd/udp-mtu/initial-stream-receive-window/...)
- tuic-v5 listener: drop `token` (v4-only per wiki)
- sudoku listener: drop httpmask.path_root/tls/host/multiplex (wiki uses dash path-root only)
MEDIUM (11):
- VMess listener: strip top-level `alterId` (per-user form in users[] only)
- VMess/VLESS/Trojan listener: drop undocumented top-level `udp`
- SS kcptun: emit plugin:kcptun + plugin-opts from kcp-tun block (m-ui + converter paths)
- m-ui hysteria2ClientProxy: add ports/hop-interval/obfs-min/obfs-max/name-cert-verify/fingerprint/handshake-timeout
- m-ui hysteria2RealmConfig: drop client-side `proxy` (listener-only)
- m-ui classicClientProxy (VMess/Trojan): add global-padding/authenticated-length/fingerprint/name-cert-verify/tlsmirror-opts/smux
- m-ui vlessClientProxy: add fingerprint/name-cert-verify/smux
- m-ui websocketClient: add headers map (was only path)
- converter TUIC v4+v5: add ip + name-cert-verify copy
- converter mekya-opts: add polling-interval-initial + h2-pool-size
- converter hysteria2: add ports/hop-interval/obfs-min-packet-size/obfs-max-packet-size
- converter applyClientWrappers: add tlsmirror-opts branch
LOW:
- Update TestGenerateListenersUsesModelTLS to assert wiki-correct VLESS (no top-level tls)
- SS client: add udp-over-tcp/udp-over-tcp-version/ip-version/smux (both paths)
- grpc-opts: add grpc-user-agent/ping-interval/max-connections/min-streams/max-streams (both paths)
- ech-opts: pass-through in copyClientTLS (both paths)
- Schema whitelist: add mekya-config.polling-interval-initial/h2-pool-size + grpc-opts 5 fields
(client-only metadata accepted by panel; mihomo ignores unknown listener fields)
Verification:
- go build ./... → PASS
- go vet ./... → clean
- go test ./... → 16/16 packages PASS
Refs: wiki-audit-1 (33 findings) + wiki-audit-2 (4 R-M follow-ups) in worklog.
fix(config): align listener/client fields with MetaCubeX wiki (round 2)
Complete field-level audit against https://wiki.metacubex.one/ for 8 protocols
(shadowsocks/vmess/vless/trojan/hysteria2/tuic-v4/tuic-v5/sudoku).
HIGH (8):
- VLESS listener: strip client-only `encryption` field (server uses `decryption`)
- mux-option: drop undocumented `brutal-opts` from all 9 listener schemas (keep `brutal` map)
- vmess/vless/trojan listener: drop fabricated top-level `ws-headers` (client uses ws-opts.headers)
- 3m-ui share: nest ws-opts.Host under headers map per proxies-transport
- hysteria2 listener: drop `handshake-timeout`/`max-idle-time` (client/TUIC only)
- m-ui hysteria2Listener: drop 6 quic-go fields (cwnd/udp-mtu/initial-stream-receive-window/...)
- tuic-v5 listener: drop `token` (v4-only per wiki)
- sudoku listener: drop httpmask.path_root/tls/host/multiplex (wiki uses dash path-root only)
MEDIUM (11):
- VMess listener: strip top-level `alterId` (per-user form in users[] only)
- VMess/VLESS/Trojan listener: drop undocumented top-level `udp`
- SS kcptun: emit plugin:kcptun + plugin-opts from kcp-tun block (m-ui + converter paths)
- m-ui hysteria2ClientProxy: add ports/hop-interval/obfs-min/obfs-max/name-cert-verify/fingerprint/handshake-timeout
- m-ui hysteria2RealmConfig: drop client-side `proxy` (listener-only)
- m-ui classicClientProxy (VMess/Trojan): add global-padding/authenticated-length/fingerprint/name-cert-verify/tlsmirror-opts/smux
- m-ui vlessClientProxy: add fingerprint/name-cert-verify/smux
- m-ui websocketClient: add headers map (was only path)
- converter TUIC v4+v5: add ip + name-cert-verify copy
- converter mekya-opts: add polling-interval-initial + h2-pool-size
- converter hysteria2: add ports/hop-interval/obfs-min-packet-size/obfs-max-packet-size
- converter applyClientWrappers: add tlsmirror-opts branch
LOW:
- Update TestGenerateListenersUsesModelTLS to assert wiki-correct VLESS (no top-level tls)
- SS client: add udp-over-tcp/udp-over-tcp-version/ip-version/smux (both paths)
- grpc-opts: add grpc-user-agent/ping-interval/max-connections/min-streams/max-streams (both paths)
- ech-opts: pass-through in copyClientTLS (both paths)
- Schema whitelist: add mekya-config.polling-interval-initial/h2-pool-size + grpc-opts 5 fields
(client-only metadata accepted by panel; mihomo ignores unknown listener fields)
Verification:
- go build ./... → PASS
- go vet ./... → clean
- go test ./... → 16/16 packages PASS
Refs: wiki-audit-1 (33 findings) + wiki-audit-2 (4 R-M follow-ups) in worklog.
fix(config): align listener/client fields with MetaCubeX wiki (round 2)
Complete field-level audit against https://wiki.metacubex.one/ for 8 protocols
(shadowsocks/vmess/vless/trojan/hysteria2/tuic-v4/tuic-v5/sudoku).
HIGH (8):
- VLESS listener: strip client-only `encryption` field (server uses `decryption`)
- mux-option: drop undocumented `brutal-opts` from all 9 listener schemas (keep `brutal` map)
- vmess/vless/trojan listener: drop fabricated top-level `ws-headers` (client uses ws-opts.headers)
- 3m-ui share: nest ws-opts.Host under headers map per proxies-transport
- hysteria2 listener: drop `handshake-timeout`/`max-idle-time` (client/TUIC only)
- m-ui hysteria2Listener: drop 6 quic-go fields (cwnd/udp-mtu/initial-stream-receive-window/...)
- tuic-v5 listener: drop `token` (v4-only per wiki)
- sudoku listener: drop httpmask.path_root/tls/host/multiplex (wiki uses dash path-root only)
MEDIUM (11):
- VMess listener: strip top-level `alterId` (per-user form in users[] only)
- VMess/VLESS/Trojan listener: drop undocumented top-level `udp`
- SS kcptun: emit plugin:kcptun + plugin-opts from kcp-tun block (m-ui + converter paths)
- m-ui hysteria2ClientProxy: add ports/hop-interval/obfs-min/obfs-max/name-cert-verify/fingerprint/handshake-timeout
- m-ui hysteria2RealmConfig: drop client-side `proxy` (listener-only)
- m-ui classicClientProxy (VMess/Trojan): add global-padding/authenticated-length/fingerprint/name-cert-verify/tlsmirror-opts/smux
- m-ui vlessClientProxy: add fingerprint/name-cert-verify/smux
- m-ui websocketClient: add headers map (was only path)
- converter TUIC v4+v5: add ip + name-cert-verify copy
- converter mekya-opts: add polling-interval-initial + h2-pool-size
- converter hysteria2: add ports/hop-interval/obfs-min-packet-size/obfs-max-packet-size
- converter applyClientWrappers: add tlsmirror-opts branch
LOW:
- Update TestGenerateListenersUsesModelTLS to assert wiki-correct VLESS (no top-level tls)
- SS client: add udp-over-tcp/udp-over-tcp-version/ip-version/smux (both paths)
- grpc-opts: add grpc-user-agent/ping-interval/max-connections/min-streams/max-streams (both paths)
- ech-opts: pass-through in copyClientTLS (both paths)
- Schema whitelist: add mekya-config.polling-interval-initial/h2-pool-size + grpc-opts 5 fields
(client-only metadata accepted by panel; mihomo ignores unknown listener fields)
Verification:
- go build ./... → PASS
- go vet ./... → clean
- go test ./... → 16/16 packages PASS
Refs: wiki-audit-1 (33 findings) + wiki-audit-2 (4 R-M follow-ups) in worklog.
fix(config): align listener/client fields with MetaCubeX wiki (round 2)
Complete field-level audit against https://wiki.metacubex.one/ for 8 protocols
(shadowsocks/vmess/vless/trojan/hysteria2/tuic-v4/tuic-v5/sudoku).
HIGH (8):
- VLESS listener: strip client-only `encryption` field (server uses `decryption`)
- mux-option: drop undocumented `brutal-opts` from all 9 listener schemas (keep `brutal` map)
- vmess/vless/trojan listener: drop fabricated top-level `ws-headers` (client uses ws-opts.headers)
- 3m-ui share: nest ws-opts.Host under headers map per proxies-transport
- hysteria2 listener: drop `handshake-timeout`/`max-idle-time` (client/TUIC only)
- m-ui hysteria2Listener: drop 6 quic-go fields (cwnd/udp-mtu/initial-stream-receive-window/...)
- tuic-v5 listener: drop `token` (v4-only per wiki)
- sudoku listener: drop httpmask.path_root/tls/host/multiplex (wiki uses dash path-root only)
MEDIUM (11):
- VMess listener: strip top-level `alterId` (per-user form in users[] only)
- VMess/VLESS/Trojan listener: drop undocumented top-level `udp`
- SS kcptun: emit plugin:kcptun + plugin-opts from kcp-tun block (m-ui + converter paths)
- m-ui hysteria2ClientProxy: add ports/hop-interval/obfs-min/obfs-max/name-cert-verify/fingerprint/handshake-timeout
- m-ui hysteria2RealmConfig: drop client-side `proxy` (listener-only)
- m-ui classicClientProxy (VMess/Trojan): add global-padding/authenticated-length/fingerprint/name-cert-verify/tlsmirror-opts/smux
- m-ui vlessClientProxy: add fingerprint/name-cert-verify/smux
- m-ui websocketClient: add headers map (was only path)
- converter TUIC v4+v5: add ip + name-cert-verify copy
- converter mekya-opts: add polling-interval-initial + h2-pool-size
- converter hysteria2: add ports/hop-interval/obfs-min-packet-size/obfs-max-packet-size
- converter applyClientWrappers: add tlsmirror-opts branch
LOW:
- Update TestGenerateListenersUsesModelTLS to assert wiki-correct VLESS (no top-level tls)
- SS client: add udp-over-tcp/udp-over-tcp-version/ip-version/smux (both paths)
- grpc-opts: add grpc-user-agent/ping-interval/max-connections/min-streams/max-streams (both paths)
- ech-opts: pass-through in copyClientTLS (both paths)
- Schema whitelist: add mekya-config.polling-interval-initial/h2-pool-size + grpc-opts 5 fields
(client-only metadata accepted by panel; mihomo ignores unknown listener fields)
Verification:
- go build ./... → PASS
- go vet ./... → clean
- go test ./... → 16/16 packages PASS
Refs: wiki-audit-1 (33 findings) + wiki-audit-2 (4 R-M follow-ups) in worklog.
fix(config): align listener/client fields with MetaCubeX wiki (round 2)
Complete field-level audit against https://wiki.metacubex.one/ for 8 protocols
(shadowsocks/vmess/vless/trojan/hysteria2/tuic-v4/tuic-v5/sudoku).
HIGH (8):
- VLESS listener: strip client-only `encryption` field (server uses `decryption`)
- mux-option: drop undocumented `brutal-opts` from all 9 listener schemas (keep `brutal` map)
- vmess/vless/trojan listener: drop fabricated top-level `ws-headers` (client uses ws-opts.headers)
- 3m-ui share: nest ws-opts.Host under headers map per proxies-transport
- hysteria2 listener: drop `handshake-timeout`/`max-idle-time` (client/TUIC only)
- m-ui hysteria2Listener: drop 6 quic-go fields (cwnd/udp-mtu/initial-stream-receive-window/...)
- tuic-v5 listener: drop `token` (v4-only per wiki)
- sudoku listener: drop httpmask.path_root/tls/host/multiplex (wiki uses dash path-root only)
MEDIUM (11):
- VMess listener: strip top-level `alterId` (per-user form in users[] only)
- VMess/VLESS/Trojan listener: drop undocumented top-level `udp`
- SS kcptun: emit plugin:kcptun + plugin-opts from kcp-tun block (m-ui + converter paths)
- m-ui hysteria2ClientProxy: add ports/hop-interval/obfs-min/obfs-max/name-cert-verify/fingerprint/handshake-timeout
- m-ui hysteria2RealmConfig: drop client-side `proxy` (listener-only)
- m-ui classicClientProxy (VMess/Trojan): add global-padding/authenticated-length/fingerprint/name-cert-verify/tlsmirror-opts/smux
- m-ui vlessClientProxy: add fingerprint/name-cert-verify/smux
- m-ui websocketClient: add headers map (was only path)
- converter TUIC v4+v5: add ip + name-cert-verify copy
- converter mekya-opts: add polling-interval-initial + h2-pool-size
- converter hysteria2: add ports/hop-interval/obfs-min-packet-size/obfs-max-packet-size
- converter applyClientWrappers: add tlsmirror-opts branch
LOW:
- Update TestGenerateListenersUsesModelTLS to assert wiki-correct VLESS (no top-level tls)
- SS client: add udp-over-tcp/udp-over-tcp-version/ip-version/smux (both paths)
- grpc-opts: add grpc-user-agent/ping-interval/max-connections/min-streams/max-streams (both paths)
- ech-opts: pass-through in copyClientTLS (both paths)
- Schema whitelist: add mekya-config.polling-interval-initial/h2-pool-size + grpc-opts 5 fields
(client-only metadata accepted by panel; mihomo ignores unknown listener fields)
Verification:
- go build ./... → PASS
- go vet ./... → clean
- go test ./... → 16/16 packages PASS
Refs: wiki-audit-1 (33 findings) + wiki-audit-2 (4 R-M follow-ups) in worklog.
fix(config): align listener/client fields with MetaCubeX wiki (round 2)
Complete field-level audit against https://wiki.metacubex.one/ for 8 protocols
(shadowsocks/vmess/vless/trojan/hysteria2/tuic-v4/tuic-v5/sudoku).
HIGH (8):
- VLESS listener: strip client-only `encryption` field (server uses `decryption`)
- mux-option: drop undocumented `brutal-opts` from all 9 listener schemas (keep `brutal` map)
- vmess/vless/trojan listener: drop fabricated top-level `ws-headers` (client uses ws-opts.headers)
- 3m-ui share: nest ws-opts.Host under headers map per proxies-transport
- hysteria2 listener: drop `handshake-timeout`/`max-idle-time` (client/TUIC only)
- m-ui hysteria2Listener: drop 6 quic-go fields (cwnd/udp-mtu/initial-stream-receive-window/...)
- tuic-v5 listener: drop `token` (v4-only per wiki)
- sudoku listener: drop httpmask.path_root/tls/host/multiplex (wiki uses dash path-root only)
MEDIUM (11):
- VMess listener: strip top-level `alterId` (per-user form in users[] only)
- VMess/VLESS/Trojan listener: drop undocumented top-level `udp`
- SS kcptun: emit plugin:kcptun + plugin-opts from kcp-tun block (m-ui + converter paths)
- m-ui hysteria2ClientProxy: add ports/hop-interval/obfs-min/obfs-max/name-cert-verify/fingerprint/handshake-timeout
- m-ui hysteria2RealmConfig: drop client-side `proxy` (listener-only)
- m-ui classicClientProxy (VMess/Trojan): add global-padding/authenticated-length/fingerprint/name-cert-verify/tlsmirror-opts/smux
- m-ui vlessClientProxy: add fingerprint/name-cert-verify/smux
- m-ui websocketClient: add headers map (was only path)
- converter TUIC v4+v5: add ip + name-cert-verify copy
- converter mekya-opts: add polling-interval-initial + h2-pool-size
- converter hysteria2: add ports/hop-interval/obfs-min-packet-size/obfs-max-packet-size
- converter applyClientWrappers: add tlsmirror-opts branch
LOW:
- Update TestGenerateListenersUsesModelTLS to assert wiki-correct VLESS (no top-level tls)
- SS client: add udp-over-tcp/udp-over-tcp-version/ip-version/smux (both paths)
- grpc-opts: add grpc-user-agent/ping-interval/max-connections/min-streams/max-streams (both paths)
- ech-opts: pass-through in copyClientTLS (both paths)
- Schema whitelist: add mekya-config.polling-interval-initial/h2-pool-size + grpc-opts 5 fields
(client-only metadata accepted by panel; mihomo ignores unknown listener fields)
Verification:
- go build ./... → PASS
- go vet ./... → clean
- go test ./... → 16/16 packages PASS
Refs: wiki-audit-1 (33 findings) + wiki-audit-2 (4 R-M follow-ups) in worklog.
fix(config): align listener/client fields with MetaCubeX wiki (round 2)
Complete field-level audit against https://wiki.metacubex.one/ for 8 protocols
(shadowsocks/vmess/vless/trojan/hysteria2/tuic-v4/tuic-v5/sudoku).
HIGH (8):
- VLESS listener: strip client-only `encryption` field (server uses `decryption`)
- mux-option: drop undocumented `brutal-opts` from all 9 listener schemas (keep `brutal` map)
- vmess/vless/trojan listener: drop fabricated top-level `ws-headers` (client uses ws-opts.headers)
- 3m-ui share: nest ws-opts.Host under headers map per proxies-transport
- hysteria2 listener: drop `handshake-timeout`/`max-idle-time` (client/TUIC only)
- m-ui hysteria2Listener: drop 6 quic-go fields (cwnd/udp-mtu/initial-stream-receive-window/...)
- tuic-v5 listener: drop `token` (v4-only per wiki)
- sudoku listener: drop httpmask.path_root/tls/host/multiplex (wiki uses dash path-root only)
MEDIUM (11):
- VMess listener: strip top-level `alterId` (per-user form in users[] only)
- VMess/VLESS/Trojan listener: drop undocumented top-level `udp`
- SS kcptun: emit plugin:kcptun + plugin-opts from kcp-tun block (m-ui + converter paths)
- m-ui hysteria2ClientProxy: add ports/hop-interval/obfs-min/obfs-max/name-cert-verify/fingerprint/handshake-timeout
- m-ui hysteria2RealmConfig: drop client-side `proxy` (listener-only)
- m-ui classicClientProxy (VMess/Trojan): add global-padding/authenticated-length/fingerprint/name-cert-verify/tlsmirror-opts/smux
- m-ui vlessClientProxy: add fingerprint/name-cert-verify/smux
- m-ui websocketClient: add headers map (was only path)
- converter TUIC v4+v5: add ip + name-cert-verify copy
- converter mekya-opts: add polling-interval-initial + h2-pool-size
- converter hysteria2: add ports/hop-interval/obfs-min-packet-size/obfs-max-packet-size
- converter applyClientWrappers: add tlsmirror-opts branch
LOW:
- Update TestGenerateListenersUsesModelTLS to assert wiki-correct VLESS (no top-level tls)
- SS client: add udp-over-tcp/udp-over-tcp-version/ip-version/smux (both paths)
- grpc-opts: add grpc-user-agent/ping-interval/max-connections/min-streams/max-streams (both paths)
- ech-opts: pass-through in copyClientTLS (both paths)
- Schema whitelist: add mekya-config.polling-interval-initial/h2-pool-size + grpc-opts 5 fields
(client-only metadata accepted by panel; mihomo ignores unknown listener fields)
Verification:
- go build ./... → PASS
- go vet ./... → clean
- go test ./... → 16/16 packages PASS
Refs: wiki-audit-1 (33 findings) + wiki-audit-2 (4 R-M follow-ups) in worklog.
fix(config): align listener/client fields with MetaCubeX wiki (round 2)
Complete field-level audit against https://wiki.metacubex.one/ for 8 protocols
(shadowsocks/vmess/vless/trojan/hysteria2/tuic-v4/tuic-v5/sudoku).
HIGH (8):
- VLESS listener: strip client-only `encryption` field (server uses `decryption`)
- mux-option: drop undocumented `brutal-opts` from all 9 listener schemas (keep `brutal` map)
- vmess/vless/trojan listener: drop fabricated top-level `ws-headers` (client uses ws-opts.headers)
- 3m-ui share: nest ws-opts.Host under headers map per proxies-transport
- hysteria2 listener: drop `handshake-timeout`/`max-idle-time` (client/TUIC only)
- m-ui hysteria2Listener: drop 6 quic-go fields (cwnd/udp-mtu/initial-stream-receive-window/...)
- tuic-v5 listener: drop `token` (v4-only per wiki)
- sudoku listener: drop httpmask.path_root/tls/host/multiplex (wiki uses dash path-root only)
MEDIUM (11):
- VMess listener: strip top-level `alterId` (per-user form in users[] only)
- VMess/VLESS/Trojan listener: drop undocumented top-level `udp`
- SS kcptun: emit plugin:kcptun + plugin-opts from kcp-tun block (m-ui + converter paths)
- m-ui hysteria2ClientProxy: add ports/hop-interval/obfs-min/obfs-max/name-cert-verify/fingerprint/handshake-timeout
- m-ui hysteria2RealmConfig: drop client-side `proxy` (listener-only)
- m-ui classicClientProxy (VMess/Trojan): add global-padding/authenticated-length/fingerprint/name-cert-verify/tlsmirror-opts/smux
- m-ui vlessClientProxy: add fingerprint/name-cert-verify/smux
- m-ui websocketClient: add headers map (was only path)
- converter TUIC v4+v5: add ip + name-cert-verify copy
- converter mekya-opts: add polling-interval-initial + h2-pool-size
- converter hysteria2: add ports/hop-interval/obfs-min-packet-size/obfs-max-packet-size
- converter applyClientWrappers: add tlsmirror-opts branch
LOW:
- Update TestGenerateListenersUsesModelTLS to assert wiki-correct VLESS (no top-level tls)
- SS client: add udp-over-tcp/udp-over-tcp-version/ip-version/smux (both paths)
- grpc-opts: add grpc-user-agent/ping-interval/max-connections/min-streams/max-streams (both paths)
- ech-opts: pass-through in copyClientTLS (both paths)
- Schema whitelist: add mekya-config.polling-interval-initial/h2-pool-size + grpc-opts 5 fields
(client-only metadata accepted by panel; mihomo ignores unknown listener fields)
Verification:
- go build ./... → PASS
- go vet ./... → clean
- go test ./... → 16/16 packages PASS
Refs: wiki-audit-1 (33 findings) + wiki-audit-2 (4 R-M follow-ups) in worklog.
fix(config): align listener/client fields with MetaCubeX wiki (round 2)
Complete field-level audit against https://wiki.metacubex.one/ for 8 protocols
(shadowsocks/vmess/vless/trojan/hysteria2/tuic-v4/tuic-v5/sudoku).
HIGH (8):
- VLESS listener: strip client-only `encryption` field (server uses `decryption`)
- mux-option: drop undocumented `brutal-opts` from all 9 listener schemas (keep `brutal` map)
- vmess/vless/trojan listener: drop fabricated top-level `ws-headers` (client uses ws-opts.headers)
- 3m-ui share: nest ws-opts.Host under headers map per proxies-transport
- hysteria2 listener: drop `handshake-timeout`/`max-idle-time` (client/TUIC only)
- m-ui hysteria2Listener: drop 6 quic-go fields (cwnd/udp-mtu/initial-stream-receive-window/...)
- tuic-v5 listener: drop `token` (v4-only per wiki)
- sudoku listener: drop httpmask.path_root/tls/host/multiplex (wiki uses dash path-root only)
MEDIUM (11):
- VMess listener: strip top-level `alterId` (per-user form in users[] only)
- VMess/VLESS/Trojan listener: drop undocumented top-level `udp`
- SS kcptun: emit plugin:kcptun + plugin-opts from kcp-tun block (m-ui + converter paths)
- m-ui hysteria2ClientProxy: add ports/hop-interval/obfs-min/obfs-max/name-cert-verify/fingerprint/handshake-timeout
- m-ui hysteria2RealmConfig: drop client-side `proxy` (listener-only)
- m-ui classicClientProxy (VMess/Trojan): add global-padding/authenticated-length/fingerprint/name-cert-verify/tlsmirror-opts/smux
- m-ui vlessClientProxy: add fingerprint/name-cert-verify/smux
- m-ui websocketClient: add headers map (was only path)
- converter TUIC v4+v5: add ip + name-cert-verify copy
- converter mekya-opts: add polling-interval-initial + h2-pool-size
- converter hysteria2: add ports/hop-interval/obfs-min-packet-size/obfs-max-packet-size
- converter applyClientWrappers: add tlsmirror-opts branch
LOW:
- Update TestGenerateListenersUsesModelTLS to assert wiki-correct VLESS (no top-level tls)
- SS client: add udp-over-tcp/udp-over-tcp-version/ip-version/smux (both paths)
- grpc-opts: add grpc-user-agent/ping-interval/max-connections/min-streams/max-streams (both paths)
- ech-opts: pass-through in copyClientTLS (both paths)
- Schema whitelist: add mekya-config.polling-interval-initial/h2-pool-size + grpc-opts 5 fields
(client-only metadata accepted by panel; mihomo ignores unknown listener fields)
Verification:
- go build ./... → PASS
- go vet ./... → clean
- go test ./... → 16/16 packages PASS
Refs: wiki-audit-1 (33 findings) + wiki-audit-2 (4 R-M follow-ups) in worklog.
fix(config): align listener/client fields with MetaCubeX wiki (round 2)
Complete field-level audit against https://wiki.metacubex.one/ for 8 protocols
(shadowsocks/vmess/vless/trojan/hysteria2/tuic-v4/tuic-v5/sudoku).
HIGH (8):
- VLESS listener: strip client-only `encryption` field (server uses `decryption`)
- mux-option: drop undocumented `brutal-opts` from all 9 listener schemas (keep `brutal` map)
- vmess/vless/trojan listener: drop fabricated top-level `ws-headers` (client uses ws-opts.headers)
- 3m-ui share: nest ws-opts.Host under headers map per proxies-transport
- hysteria2 listener: drop `handshake-timeout`/`max-idle-time` (client/TUIC only)
- m-ui hysteria2Listener: drop 6 quic-go fields (cwnd/udp-mtu/initial-stream-receive-window/...)
- tuic-v5 listener: drop `token` (v4-only per wiki)
- sudoku listener: drop httpmask.path_root/tls/host/multiplex (wiki uses dash path-root only)
MEDIUM (11):
- VMess listener: strip top-level `alterId` (per-user form in users[] only)
- VMess/VLESS/Trojan listener: drop undocumented top-level `udp`
- SS kcptun: emit plugin:kcptun + plugin-opts from kcp-tun block (m-ui + converter paths)
- m-ui hysteria2ClientProxy: add ports/hop-interval/obfs-min/obfs-max/name-cert-verify/fingerprint/handshake-timeout
- m-ui hysteria2RealmConfig: drop client-side `proxy` (listener-only)
- m-ui classicClientProxy (VMess/Trojan): add global-padding/authenticated-length/fingerprint/name-cert-verify/tlsmirror-opts/smux
- m-ui vlessClientProxy: add fingerprint/name-cert-verify/smux
- m-ui websocketClient: add headers map (was only path)
- converter TUIC v4+v5: add ip + name-cert-verify copy
- converter mekya-opts: add polling-interval-initial + h2-pool-size
- converter hysteria2: add ports/hop-interval/obfs-min-packet-size/obfs-max-packet-size
- converter applyClientWrappers: add tlsmirror-opts branch
LOW:
- Update TestGenerateListenersUsesModelTLS to assert wiki-correct VLESS (no top-level tls)
- SS client: add udp-over-tcp/udp-over-tcp-version/ip-version/smux (both paths)
- grpc-opts: add grpc-user-agent/ping-interval/max-connections/min-streams/max-streams (both paths)
- ech-opts: pass-through in copyClientTLS (both paths)
- Schema whitelist: add mekya-config.polling-interval-initial/h2-pool-size + grpc-opts 5 fields
(client-only metadata accepted by panel; mihomo ignores unknown listener fields)
Verification:
- go build ./... → PASS
- go vet ./... → clean
- go test ./... → 16/16 packages PASS
Refs: wiki-audit-1 (33 findings) + wiki-audit-2 (4 R-M follow-ups) in worklog.
fix(config): align listener/client fields with MetaCubeX wiki (round 2)
Complete field-level audit against https://wiki.metacubex.one/ for 8 protocols
(shadowsocks/vmess/vless/trojan/hysteria2/tuic-v4/tuic-v5/sudoku).
HIGH (8):
- VLESS listener: strip client-only `encryption` field (server uses `decryption`)
- mux-option: drop undocumented `brutal-opts` from all 9 listener schemas (keep `brutal` map)
- vmess/vless/trojan listener: drop fabricated top-level `ws-headers` (client uses ws-opts.headers)
- 3m-ui share: nest ws-opts.Host under headers map per proxies-transport
- hysteria2 listener: drop `handshake-timeout`/`max-idle-time` (client/TUIC only)
- m-ui hysteria2Listener: drop 6 quic-go fields (cwnd/udp-mtu/initial-stream-receive-window/...)
- tuic-v5 listener: drop `token` (v4-only per wiki)
- sudoku listener: drop httpmask.path_root/tls/host/multiplex (wiki uses dash path-root only)
MEDIUM (11):
- VMess listener: strip top-level `alterId` (per-user form in users[] only)
- VMess/VLESS/Trojan listener: drop undocumented top-level `udp`
- SS kcptun: emit plugin:kcptun + plugin-opts from kcp-tun block (m-ui + converter paths)
- m-ui hysteria2ClientProxy: add ports/hop-interval/obfs-min/obfs-max/name-cert-verify/fingerprint/handshake-timeout
- m-ui hysteria2RealmConfig: drop client-side `proxy` (listener-only)
- m-ui classicClientProxy (VMess/Trojan): add global-padding/authenticated-length/fingerprint/name-cert-verify/tlsmirror-opts/smux
- m-ui vlessClientProxy: add fingerprint/name-cert-verify/smux
- m-ui websocketClient: add headers map (was only path)
- converter TUIC v4+v5: add ip + name-cert-verify copy
- converter mekya-opts: add polling-interval-initial + h2-pool-size
- converter hysteria2: add ports/hop-interval/obfs-min-packet-size/obfs-max-packet-size
- converter applyClientWrappers: add tlsmirror-opts branch
LOW:
- Update TestGenerateListenersUsesModelTLS to assert wiki-correct VLESS (no top-level tls)
- SS client: add udp-over-tcp/udp-over-tcp-version/ip-version/smux (both paths)
- grpc-opts: add grpc-user-agent/ping-interval/max-connections/min-streams/max-streams (both paths)
- ech-opts: pass-through in copyClientTLS (both paths)
- Schema whitelist: add mekya-config.polling-interval-initial/h2-pool-size + grpc-opts 5 fields
(client-only metadata accepted by panel; mihomo ignores unknown listener fields)
Verification:
- go build ./... → PASS
- go vet ./... → clean
- go test ./... → 16/16 packages PASS
Refs: wiki-audit-1 (33 findings) + wiki-audit-2 (4 R-M follow-ups) in worklog.
fix(config): align listener/client fields with MetaCubeX wiki (round 2)
Complete field-level audit against https://wiki.metacubex.one/ for 8 protocols
(shadowsocks/vmess/vless/trojan/hysteria2/tuic-v4/tuic-v5/sudoku).
HIGH (8):
- VLESS listener: strip client-only `encryption` field (server uses `decryption`)
- mux-option: drop undocumented `brutal-opts` from all 9 listener schemas (keep `brutal` map)
- vmess/vless/trojan listener: drop fabricated top-level `ws-headers` (client uses ws-opts.headers)
- 3m-ui share: nest ws-opts.Host under headers map per proxies-transport
- hysteria2 listener: drop `handshake-timeout`/`max-idle-time` (client/TUIC only)
- m-ui hysteria2Listener: drop 6 quic-go fields (cwnd/udp-mtu/initial-stream-receive-window/...)
- tuic-v5 listener: drop `token` (v4-only per wiki)
- sudoku listener: drop httpmask.path_root/tls/host/multiplex (wiki uses dash path-root only)
MEDIUM (11):
- VMess listener: strip top-level `alterId` (per-user form in users[] only)
- VMess/VLESS/Trojan listener: drop undocumented top-level `udp`
- SS kcptun: emit plugin:kcptun + plugin-opts from kcp-tun block (m-ui + converter paths)
- m-ui hysteria2ClientProxy: add ports/hop-interval/obfs-min/obfs-max/name-cert-verify/fingerprint/handshake-timeout
- m-ui hysteria2RealmConfig: drop client-side `proxy` (listener-only)
- m-ui classicClientProxy (VMess/Trojan): add global-padding/authenticated-length/fingerprint/name-cert-verify/tlsmirror-opts/smux
- m-ui vlessClientProxy: add fingerprint/name-cert-verify/smux
- m-ui websocketClient: add headers map (was only path)
- converter TUIC v4+v5: add ip + name-cert-verify copy
- converter mekya-opts: add polling-interval-initial + h2-pool-size
- converter hysteria2: add ports/hop-interval/obfs-min-packet-size/obfs-max-packet-size
- converter applyClientWrappers: add tlsmirror-opts branch
LOW:
- Update TestGenerateListenersUsesModelTLS to assert wiki-correct VLESS (no top-level tls)
- SS client: add udp-over-tcp/udp-over-tcp-version/ip-version/smux (both paths)
- grpc-opts: add grpc-user-agent/ping-interval/max-connections/min-streams/max-streams (both paths)
- ech-opts: pass-through in copyClientTLS (both paths)
- Schema whitelist: add mekya-config.polling-interval-initial/h2-pool-size + grpc-opts 5 fields
(client-only metadata accepted by panel; mihomo ignores unknown listener fields)
Verification:
- go build ./... → PASS
- go vet ./... → clean
- go test ./... → 16/16 packages PASS
Refs: wiki-audit-1 (33 findings) + wiki-audit-2 (4 R-M follow-ups) in worklog.
2026-09-03 15:14:39 +00:00
Z User d393114a3b fix(config): align listener/client fields with MetaCubeX wiki
- Client SS type is "ss" (not listener name shadowsocks)
- Drop TUIC/Hy2 server-only keys from client export
- Strip simple-obfs enable from SS plugin-opts
- Do not emit top-level tls on VLESS/VMess/Trojan listeners
- Strip client-only keys (sni, skip-cert-verify, *-opts) from listener YAML
fix(config): align listener/client fields with MetaCubeX wiki
- Client SS type is "ss" (not listener name shadowsocks)
- Drop TUIC/Hy2 server-only keys from client export
- Strip simple-obfs enable from SS plugin-opts
- Do not emit top-level tls on VLESS/VMess/Trojan listeners
- Strip client-only keys (sni, skip-cert-verify, *-opts) from listener YAML
fix(config): align listener/client fields with MetaCubeX wiki
- Client SS type is "ss" (not listener name shadowsocks)
- Drop TUIC/Hy2 server-only keys from client export
- Strip simple-obfs enable from SS plugin-opts
- Do not emit top-level tls on VLESS/VMess/Trojan listeners
- Strip client-only keys (sni, skip-cert-verify, *-opts) from listener YAML
fix(config): align listener/client fields with MetaCubeX wiki
- Client SS type is "ss" (not listener name shadowsocks)
- Drop TUIC/Hy2 server-only keys from client export
- Strip simple-obfs enable from SS plugin-opts
- Do not emit top-level tls on VLESS/VMess/Trojan listeners
- Strip client-only keys (sni, skip-cert-verify, *-opts) from listener YAML
fix(config): align listener/client fields with MetaCubeX wiki
- Client SS type is "ss" (not listener name shadowsocks)
- Drop TUIC/Hy2 server-only keys from client export
- Strip simple-obfs enable from SS plugin-opts
- Do not emit top-level tls on VLESS/VMess/Trojan listeners
- Strip client-only keys (sni, skip-cert-verify, *-opts) from listener YAML
fix(config): align listener/client fields with MetaCubeX wiki
- Client SS type is "ss" (not listener name shadowsocks)
- Drop TUIC/Hy2 server-only keys from client export
- Strip simple-obfs enable from SS plugin-opts
- Do not emit top-level tls on VLESS/VMess/Trojan listeners
- Strip client-only keys (sni, skip-cert-verify, *-opts) from listener YAML
fix(config): align listener/client fields with MetaCubeX wiki
- Client SS type is "ss" (not listener name shadowsocks)
- Drop TUIC/Hy2 server-only keys from client export
- Strip simple-obfs enable from SS plugin-opts
- Do not emit top-level tls on VLESS/VMess/Trojan listeners
- Strip client-only keys (sni, skip-cert-verify, *-opts) from listener YAML
fix(config): align listener/client fields with MetaCubeX wiki
- Client SS type is "ss" (not listener name shadowsocks)
- Drop TUIC/Hy2 server-only keys from client export
- Strip simple-obfs enable from SS plugin-opts
- Do not emit top-level tls on VLESS/VMess/Trojan listeners
- Strip client-only keys (sni, skip-cert-verify, *-opts) from listener YAML
fix(config): align listener/client fields with MetaCubeX wiki
- Client SS type is "ss" (not listener name shadowsocks)
- Drop TUIC/Hy2 server-only keys from client export
- Strip simple-obfs enable from SS plugin-opts
- Do not emit top-level tls on VLESS/VMess/Trojan listeners
- Strip client-only keys (sni, skip-cert-verify, *-opts) from listener YAML
fix(config): align listener/client fields with MetaCubeX wiki
- Client SS type is "ss" (not listener name shadowsocks)
- Drop TUIC/Hy2 server-only keys from client export
- Strip simple-obfs enable from SS plugin-opts
- Do not emit top-level tls on VLESS/VMess/Trojan listeners
- Strip client-only keys (sni, skip-cert-verify, *-opts) from listener YAML
fix(config): align listener/client fields with MetaCubeX wiki
- Client SS type is "ss" (not listener name shadowsocks)
- Drop TUIC/Hy2 server-only keys from client export
- Strip simple-obfs enable from SS plugin-opts
- Do not emit top-level tls on VLESS/VMess/Trojan listeners
- Strip client-only keys (sni, skip-cert-verify, *-opts) from listener YAML
fix(config): align listener/client fields with MetaCubeX wiki
- Client SS type is "ss" (not listener name shadowsocks)
- Drop TUIC/Hy2 server-only keys from client export
- Strip simple-obfs enable from SS plugin-opts
- Do not emit top-level tls on VLESS/VMess/Trojan listeners
- Strip client-only keys (sni, skip-cert-verify, *-opts) from listener YAML
2026-09-02 15:12:32 +00:00
Z User 4854f18753 feat: split TUIC into TUIC v4 and TUIC v5 in protocol selector
The protocol dropdown now shows 'TUIC v4' and 'TUIC v5' as separate
options instead of a single 'tuic'. This makes it clear which
authentication mode the listener uses:
- TUIC v4: token-based auth (token: ["..."])
- TUIC v5: UUID+password auth (users: {UUID: PASSWORD})
Implementation:
- Frontend: PROTOCOLS array splits 'tuic' into 'tuic-v4' and 'tuic-v5'
Select shows them as separate options. Token field only shows for v4.
- Backend: tuic-v4 and tuic-v5 are accepted as valid protocol names
in schema registry, compiler registry, autofill, and mihomo listener
protocol list. Generator normalizes tuic-v4/tuic-v5 to 'tuic' for
Mihomo (which only has one 'tuic' type).
- Compiler: TUICCompiler gets a 'kind' field. tuic-v4 compiler ensures
token is present and removes users. tuic-v5 compiler uses users map.
- Existing 'tuic' protocol still works (backward compatible).
- autofill: tuic-v4 and tuic-v5 both call autofillTUICUsers (which
correctly handles token-vs-users logic).
Verification: go build/vet/test PASS, npm run build PASS.
feat: split TUIC into TUIC v4 and TUIC v5 in protocol selector
The protocol dropdown now shows 'TUIC v4' and 'TUIC v5' as separate
options instead of a single 'tuic'. This makes it clear which
authentication mode the listener uses:
- TUIC v4: token-based auth (token: ["..."])
- TUIC v5: UUID+password auth (users: {UUID: PASSWORD})
Implementation:
- Frontend: PROTOCOLS array splits 'tuic' into 'tuic-v4' and 'tuic-v5'
Select shows them as separate options. Token field only shows for v4.
- Backend: tuic-v4 and tuic-v5 are accepted as valid protocol names
in schema registry, compiler registry, autofill, and mihomo listener
protocol list. Generator normalizes tuic-v4/tuic-v5 to 'tuic' for
Mihomo (which only has one 'tuic' type).
- Compiler: TUICCompiler gets a 'kind' field. tuic-v4 compiler ensures
token is present and removes users. tuic-v5 compiler uses users map.
- Existing 'tuic' protocol still works (backward compatible).
- autofill: tuic-v4 and tuic-v5 both call autofillTUICUsers (which
correctly handles token-vs-users logic).
Verification: go build/vet/test PASS, npm run build PASS.
feat: split TUIC into TUIC v4 and TUIC v5 in protocol selector
The protocol dropdown now shows 'TUIC v4' and 'TUIC v5' as separate
options instead of a single 'tuic'. This makes it clear which
authentication mode the listener uses:
- TUIC v4: token-based auth (token: ["..."])
- TUIC v5: UUID+password auth (users: {UUID: PASSWORD})
Implementation:
- Frontend: PROTOCOLS array splits 'tuic' into 'tuic-v4' and 'tuic-v5'
Select shows them as separate options. Token field only shows for v4.
- Backend: tuic-v4 and tuic-v5 are accepted as valid protocol names
in schema registry, compiler registry, autofill, and mihomo listener
protocol list. Generator normalizes tuic-v4/tuic-v5 to 'tuic' for
Mihomo (which only has one 'tuic' type).
- Compiler: TUICCompiler gets a 'kind' field. tuic-v4 compiler ensures
token is present and removes users. tuic-v5 compiler uses users map.
- Existing 'tuic' protocol still works (backward compatible).
- autofill: tuic-v4 and tuic-v5 both call autofillTUICUsers (which
correctly handles token-vs-users logic).
Verification: go build/vet/test PASS, npm run build PASS.
feat: split TUIC into TUIC v4 and TUIC v5 in protocol selector
The protocol dropdown now shows 'TUIC v4' and 'TUIC v5' as separate
options instead of a single 'tuic'. This makes it clear which
authentication mode the listener uses:
- TUIC v4: token-based auth (token: ["..."])
- TUIC v5: UUID+password auth (users: {UUID: PASSWORD})
Implementation:
- Frontend: PROTOCOLS array splits 'tuic' into 'tuic-v4' and 'tuic-v5'
Select shows them as separate options. Token field only shows for v4.
- Backend: tuic-v4 and tuic-v5 are accepted as valid protocol names
in schema registry, compiler registry, autofill, and mihomo listener
protocol list. Generator normalizes tuic-v4/tuic-v5 to 'tuic' for
Mihomo (which only has one 'tuic' type).
- Compiler: TUICCompiler gets a 'kind' field. tuic-v4 compiler ensures
token is present and removes users. tuic-v5 compiler uses users map.
- Existing 'tuic' protocol still works (backward compatible).
- autofill: tuic-v4 and tuic-v5 both call autofillTUICUsers (which
correctly handles token-vs-users logic).
Verification: go build/vet/test PASS, npm run build PASS.
feat: split TUIC into TUIC v4 and TUIC v5 in protocol selector
The protocol dropdown now shows 'TUIC v4' and 'TUIC v5' as separate
options instead of a single 'tuic'. This makes it clear which
authentication mode the listener uses:
- TUIC v4: token-based auth (token: ["..."])
- TUIC v5: UUID+password auth (users: {UUID: PASSWORD})
Implementation:
- Frontend: PROTOCOLS array splits 'tuic' into 'tuic-v4' and 'tuic-v5'
Select shows them as separate options. Token field only shows for v4.
- Backend: tuic-v4 and tuic-v5 are accepted as valid protocol names
in schema registry, compiler registry, autofill, and mihomo listener
protocol list. Generator normalizes tuic-v4/tuic-v5 to 'tuic' for
Mihomo (which only has one 'tuic' type).
- Compiler: TUICCompiler gets a 'kind' field. tuic-v4 compiler ensures
token is present and removes users. tuic-v5 compiler uses users map.
- Existing 'tuic' protocol still works (backward compatible).
- autofill: tuic-v4 and tuic-v5 both call autofillTUICUsers (which
correctly handles token-vs-users logic).
Verification: go build/vet/test PASS, npm run build PASS.
feat: split TUIC into TUIC v4 and TUIC v5 in protocol selector
The protocol dropdown now shows 'TUIC v4' and 'TUIC v5' as separate
options instead of a single 'tuic'. This makes it clear which
authentication mode the listener uses:
- TUIC v4: token-based auth (token: ["..."])
- TUIC v5: UUID+password auth (users: {UUID: PASSWORD})
Implementation:
- Frontend: PROTOCOLS array splits 'tuic' into 'tuic-v4' and 'tuic-v5'
Select shows them as separate options. Token field only shows for v4.
- Backend: tuic-v4 and tuic-v5 are accepted as valid protocol names
in schema registry, compiler registry, autofill, and mihomo listener
protocol list. Generator normalizes tuic-v4/tuic-v5 to 'tuic' for
Mihomo (which only has one 'tuic' type).
- Compiler: TUICCompiler gets a 'kind' field. tuic-v4 compiler ensures
token is present and removes users. tuic-v5 compiler uses users map.
- Existing 'tuic' protocol still works (backward compatible).
- autofill: tuic-v4 and tuic-v5 both call autofillTUICUsers (which
correctly handles token-vs-users logic).
Verification: go build/vet/test PASS, npm run build PASS.
feat: split TUIC into TUIC v4 and TUIC v5 in protocol selector
The protocol dropdown now shows 'TUIC v4' and 'TUIC v5' as separate
options instead of a single 'tuic'. This makes it clear which
authentication mode the listener uses:
- TUIC v4: token-based auth (token: ["..."])
- TUIC v5: UUID+password auth (users: {UUID: PASSWORD})
Implementation:
- Frontend: PROTOCOLS array splits 'tuic' into 'tuic-v4' and 'tuic-v5'
Select shows them as separate options. Token field only shows for v4.
- Backend: tuic-v4 and tuic-v5 are accepted as valid protocol names
in schema registry, compiler registry, autofill, and mihomo listener
protocol list. Generator normalizes tuic-v4/tuic-v5 to 'tuic' for
Mihomo (which only has one 'tuic' type).
- Compiler: TUICCompiler gets a 'kind' field. tuic-v4 compiler ensures
token is present and removes users. tuic-v5 compiler uses users map.
- Existing 'tuic' protocol still works (backward compatible).
- autofill: tuic-v4 and tuic-v5 both call autofillTUICUsers (which
correctly handles token-vs-users logic).
Verification: go build/vet/test PASS, npm run build PASS.
feat: split TUIC into TUIC v4 and TUIC v5 in protocol selector
The protocol dropdown now shows 'TUIC v4' and 'TUIC v5' as separate
options instead of a single 'tuic'. This makes it clear which
authentication mode the listener uses:
- TUIC v4: token-based auth (token: ["..."])
- TUIC v5: UUID+password auth (users: {UUID: PASSWORD})
Implementation:
- Frontend: PROTOCOLS array splits 'tuic' into 'tuic-v4' and 'tuic-v5'
Select shows them as separate options. Token field only shows for v4.
- Backend: tuic-v4 and tuic-v5 are accepted as valid protocol names
in schema registry, compiler registry, autofill, and mihomo listener
protocol list. Generator normalizes tuic-v4/tuic-v5 to 'tuic' for
Mihomo (which only has one 'tuic' type).
- Compiler: TUICCompiler gets a 'kind' field. tuic-v4 compiler ensures
token is present and removes users. tuic-v5 compiler uses users map.
- Existing 'tuic' protocol still works (backward compatible).
- autofill: tuic-v4 and tuic-v5 both call autofillTUICUsers (which
correctly handles token-vs-users logic).
Verification: go build/vet/test PASS, npm run build PASS.
feat: split TUIC into TUIC v4 and TUIC v5 in protocol selector
The protocol dropdown now shows 'TUIC v4' and 'TUIC v5' as separate
options instead of a single 'tuic'. This makes it clear which
authentication mode the listener uses:
- TUIC v4: token-based auth (token: ["..."])
- TUIC v5: UUID+password auth (users: {UUID: PASSWORD})
Implementation:
- Frontend: PROTOCOLS array splits 'tuic' into 'tuic-v4' and 'tuic-v5'
Select shows them as separate options. Token field only shows for v4.
- Backend: tuic-v4 and tuic-v5 are accepted as valid protocol names
in schema registry, compiler registry, autofill, and mihomo listener
protocol list. Generator normalizes tuic-v4/tuic-v5 to 'tuic' for
Mihomo (which only has one 'tuic' type).
- Compiler: TUICCompiler gets a 'kind' field. tuic-v4 compiler ensures
token is present and removes users. tuic-v5 compiler uses users map.
- Existing 'tuic' protocol still works (backward compatible).
- autofill: tuic-v4 and tuic-v5 both call autofillTUICUsers (which
correctly handles token-vs-users logic).
Verification: go build/vet/test PASS, npm run build PASS.
feat: split TUIC into TUIC v4 and TUIC v5 in protocol selector
The protocol dropdown now shows 'TUIC v4' and 'TUIC v5' as separate
options instead of a single 'tuic'. This makes it clear which
authentication mode the listener uses:
- TUIC v4: token-based auth (token: ["..."])
- TUIC v5: UUID+password auth (users: {UUID: PASSWORD})
Implementation:
- Frontend: PROTOCOLS array splits 'tuic' into 'tuic-v4' and 'tuic-v5'
Select shows them as separate options. Token field only shows for v4.
- Backend: tuic-v4 and tuic-v5 are accepted as valid protocol names
in schema registry, compiler registry, autofill, and mihomo listener
protocol list. Generator normalizes tuic-v4/tuic-v5 to 'tuic' for
Mihomo (which only has one 'tuic' type).
- Compiler: TUICCompiler gets a 'kind' field. tuic-v4 compiler ensures
token is present and removes users. tuic-v5 compiler uses users map.
- Existing 'tuic' protocol still works (backward compatible).
- autofill: tuic-v4 and tuic-v5 both call autofillTUICUsers (which
correctly handles token-vs-users logic).
Verification: go build/vet/test PASS, npm run build PASS.
feat: split TUIC into TUIC v4 and TUIC v5 in protocol selector
The protocol dropdown now shows 'TUIC v4' and 'TUIC v5' as separate
options instead of a single 'tuic'. This makes it clear which
authentication mode the listener uses:
- TUIC v4: token-based auth (token: ["..."])
- TUIC v5: UUID+password auth (users: {UUID: PASSWORD})
Implementation:
- Frontend: PROTOCOLS array splits 'tuic' into 'tuic-v4' and 'tuic-v5'
Select shows them as separate options. Token field only shows for v4.
- Backend: tuic-v4 and tuic-v5 are accepted as valid protocol names
in schema registry, compiler registry, autofill, and mihomo listener
protocol list. Generator normalizes tuic-v4/tuic-v5 to 'tuic' for
Mihomo (which only has one 'tuic' type).
- Compiler: TUICCompiler gets a 'kind' field. tuic-v4 compiler ensures
token is present and removes users. tuic-v5 compiler uses users map.
- Existing 'tuic' protocol still works (backward compatible).
- autofill: tuic-v4 and tuic-v5 both call autofillTUICUsers (which
correctly handles token-vs-users logic).
Verification: go build/vet/test PASS, npm run build PASS.
feat: split TUIC into TUIC v4 and TUIC v5 in protocol selector
The protocol dropdown now shows 'TUIC v4' and 'TUIC v5' as separate
options instead of a single 'tuic'. This makes it clear which
authentication mode the listener uses:
- TUIC v4: token-based auth (token: ["..."])
- TUIC v5: UUID+password auth (users: {UUID: PASSWORD})
Implementation:
- Frontend: PROTOCOLS array splits 'tuic' into 'tuic-v4' and 'tuic-v5'
Select shows them as separate options. Token field only shows for v4.
- Backend: tuic-v4 and tuic-v5 are accepted as valid protocol names
in schema registry, compiler registry, autofill, and mihomo listener
protocol list. Generator normalizes tuic-v4/tuic-v5 to 'tuic' for
Mihomo (which only has one 'tuic' type).
- Compiler: TUICCompiler gets a 'kind' field. tuic-v4 compiler ensures
token is present and removes users. tuic-v5 compiler uses users map.
- Existing 'tuic' protocol still works (backward compatible).
- autofill: tuic-v4 and tuic-v5 both call autofillTUICUsers (which
correctly handles token-vs-users logic).
Verification: go build/vet/test PASS, npm run build PASS.
2026-08-31 15:04:36 +00:00
Z User 4190024234 fix(tuic): token field must be slice not string
Same class of bug as trusttunnel network: Mihomo expects TUIC v4 token
as an array (token: ["TOKEN"]), but the frontend stored a single
token as a string. Mihomo rejected with 'token' is not a slice.
Fix:
- Frontend: token always stored as array (even when single token)
- Backend: TUICCompiler converts string token to []string{token}
for legacy configs
Also audited all other array-type fields:
- alpn: Select mode=tags → array ✅
- quic-versions: Select mode=tags → array ✅
- short-id: Select mode=tags → array ✅
- server-names: Select mode=tags → array ✅
- network (trusttunnel): mode=multiple → array ✅ (fixed in prev commit)
- token (tuic v4): now always array ✅ (this fix)
No other type mismatches found.
fix(tuic): token field must be slice not string
Same class of bug as trusttunnel network: Mihomo expects TUIC v4 token
as an array (token: ["TOKEN"]), but the frontend stored a single
token as a string. Mihomo rejected with 'token' is not a slice.
Fix:
- Frontend: token always stored as array (even when single token)
- Backend: TUICCompiler converts string token to []string{token}
for legacy configs
Also audited all other array-type fields:
- alpn: Select mode=tags → array ✅
- quic-versions: Select mode=tags → array ✅
- short-id: Select mode=tags → array ✅
- server-names: Select mode=tags → array ✅
- network (trusttunnel): mode=multiple → array ✅ (fixed in prev commit)
- token (tuic v4): now always array ✅ (this fix)
No other type mismatches found.
fix(tuic): token field must be slice not string
Same class of bug as trusttunnel network: Mihomo expects TUIC v4 token
as an array (token: ["TOKEN"]), but the frontend stored a single
token as a string. Mihomo rejected with 'token' is not a slice.
Fix:
- Frontend: token always stored as array (even when single token)
- Backend: TUICCompiler converts string token to []string{token}
for legacy configs
Also audited all other array-type fields:
- alpn: Select mode=tags → array ✅
- quic-versions: Select mode=tags → array ✅
- short-id: Select mode=tags → array ✅
- server-names: Select mode=tags → array ✅
- network (trusttunnel): mode=multiple → array ✅ (fixed in prev commit)
- token (tuic v4): now always array ✅ (this fix)
No other type mismatches found.
fix(tuic): token field must be slice not string
Same class of bug as trusttunnel network: Mihomo expects TUIC v4 token
as an array (token: ["TOKEN"]), but the frontend stored a single
token as a string. Mihomo rejected with 'token' is not a slice.
Fix:
- Frontend: token always stored as array (even when single token)
- Backend: TUICCompiler converts string token to []string{token}
for legacy configs
Also audited all other array-type fields:
- alpn: Select mode=tags → array ✅
- quic-versions: Select mode=tags → array ✅
- short-id: Select mode=tags → array ✅
- server-names: Select mode=tags → array ✅
- network (trusttunnel): mode=multiple → array ✅ (fixed in prev commit)
- token (tuic v4): now always array ✅ (this fix)
No other type mismatches found.
fix(tuic): token field must be slice not string
Same class of bug as trusttunnel network: Mihomo expects TUIC v4 token
as an array (token: ["TOKEN"]), but the frontend stored a single
token as a string. Mihomo rejected with 'token' is not a slice.
Fix:
- Frontend: token always stored as array (even when single token)
- Backend: TUICCompiler converts string token to []string{token}
for legacy configs
Also audited all other array-type fields:
- alpn: Select mode=tags → array ✅
- quic-versions: Select mode=tags → array ✅
- short-id: Select mode=tags → array ✅
- server-names: Select mode=tags → array ✅
- network (trusttunnel): mode=multiple → array ✅ (fixed in prev commit)
- token (tuic v4): now always array ✅ (this fix)
No other type mismatches found.
fix(tuic): token field must be slice not string
Same class of bug as trusttunnel network: Mihomo expects TUIC v4 token
as an array (token: ["TOKEN"]), but the frontend stored a single
token as a string. Mihomo rejected with 'token' is not a slice.
Fix:
- Frontend: token always stored as array (even when single token)
- Backend: TUICCompiler converts string token to []string{token}
for legacy configs
Also audited all other array-type fields:
- alpn: Select mode=tags → array ✅
- quic-versions: Select mode=tags → array ✅
- short-id: Select mode=tags → array ✅
- server-names: Select mode=tags → array ✅
- network (trusttunnel): mode=multiple → array ✅ (fixed in prev commit)
- token (tuic v4): now always array ✅ (this fix)
No other type mismatches found.
fix(tuic): token field must be slice not string
Same class of bug as trusttunnel network: Mihomo expects TUIC v4 token
as an array (token: ["TOKEN"]), but the frontend stored a single
token as a string. Mihomo rejected with 'token' is not a slice.
Fix:
- Frontend: token always stored as array (even when single token)
- Backend: TUICCompiler converts string token to []string{token}
for legacy configs
Also audited all other array-type fields:
- alpn: Select mode=tags → array ✅
- quic-versions: Select mode=tags → array ✅
- short-id: Select mode=tags → array ✅
- server-names: Select mode=tags → array ✅
- network (trusttunnel): mode=multiple → array ✅ (fixed in prev commit)
- token (tuic v4): now always array ✅ (this fix)
No other type mismatches found.
fix(tuic): token field must be slice not string
Same class of bug as trusttunnel network: Mihomo expects TUIC v4 token
as an array (token: ["TOKEN"]), but the frontend stored a single
token as a string. Mihomo rejected with 'token' is not a slice.
Fix:
- Frontend: token always stored as array (even when single token)
- Backend: TUICCompiler converts string token to []string{token}
for legacy configs
Also audited all other array-type fields:
- alpn: Select mode=tags → array ✅
- quic-versions: Select mode=tags → array ✅
- short-id: Select mode=tags → array ✅
- server-names: Select mode=tags → array ✅
- network (trusttunnel): mode=multiple → array ✅ (fixed in prev commit)
- token (tuic v4): now always array ✅ (this fix)
No other type mismatches found.
fix(tuic): token field must be slice not string
Same class of bug as trusttunnel network: Mihomo expects TUIC v4 token
as an array (token: ["TOKEN"]), but the frontend stored a single
token as a string. Mihomo rejected with 'token' is not a slice.
Fix:
- Frontend: token always stored as array (even when single token)
- Backend: TUICCompiler converts string token to []string{token}
for legacy configs
Also audited all other array-type fields:
- alpn: Select mode=tags → array ✅
- quic-versions: Select mode=tags → array ✅
- short-id: Select mode=tags → array ✅
- server-names: Select mode=tags → array ✅
- network (trusttunnel): mode=multiple → array ✅ (fixed in prev commit)
- token (tuic v4): now always array ✅ (this fix)
No other type mismatches found.
fix(tuic): token field must be slice not string
Same class of bug as trusttunnel network: Mihomo expects TUIC v4 token
as an array (token: ["TOKEN"]), but the frontend stored a single
token as a string. Mihomo rejected with 'token' is not a slice.
Fix:
- Frontend: token always stored as array (even when single token)
- Backend: TUICCompiler converts string token to []string{token}
for legacy configs
Also audited all other array-type fields:
- alpn: Select mode=tags → array ✅
- quic-versions: Select mode=tags → array ✅
- short-id: Select mode=tags → array ✅
- server-names: Select mode=tags → array ✅
- network (trusttunnel): mode=multiple → array ✅ (fixed in prev commit)
- token (tuic v4): now always array ✅ (this fix)
No other type mismatches found.
fix(tuic): token field must be slice not string
Same class of bug as trusttunnel network: Mihomo expects TUIC v4 token
as an array (token: ["TOKEN"]), but the frontend stored a single
token as a string. Mihomo rejected with 'token' is not a slice.
Fix:
- Frontend: token always stored as array (even when single token)
- Backend: TUICCompiler converts string token to []string{token}
for legacy configs
Also audited all other array-type fields:
- alpn: Select mode=tags → array ✅
- quic-versions: Select mode=tags → array ✅
- short-id: Select mode=tags → array ✅
- server-names: Select mode=tags → array ✅
- network (trusttunnel): mode=multiple → array ✅ (fixed in prev commit)
- token (tuic v4): now always array ✅ (this fix)
No other type mismatches found.
fix(tuic): token field must be slice not string
Same class of bug as trusttunnel network: Mihomo expects TUIC v4 token
as an array (token: ["TOKEN"]), but the frontend stored a single
token as a string. Mihomo rejected with 'token' is not a slice.
Fix:
- Frontend: token always stored as array (even when single token)
- Backend: TUICCompiler converts string token to []string{token}
for legacy configs
Also audited all other array-type fields:
- alpn: Select mode=tags → array ✅
- quic-versions: Select mode=tags → array ✅
- short-id: Select mode=tags → array ✅
- server-names: Select mode=tags → array ✅
- network (trusttunnel): mode=multiple → array ✅ (fixed in prev commit)
- token (tuic v4): now always array ✅ (this fix)
No other type mismatches found.
2026-08-31 14:28:21 +00:00
Z User 156b21fcc1 fix(trusttunnel): network field must be slice not string
Mihomo expects network: ["tcp", "udp"] (array) for TrustTunnel
listeners. The frontend Select stored a single string ("tcp" or
"udp"), which copyConfigPassthrough emitted as network: "tcp"
(string). Mihomo rejected with: 'network' is not a slice.
Fix:
- Frontend: network Select changed to mode="multiple" (multi-select)
Storing as array, reading as array (backward compatible with string)
- Backend: TrustTunnelCompiler.Compile converts string network to
[]string{network} for legacy configs that still have a string
Official docs: network: ["tcp", "udp"] # http2+http3
fix(trusttunnel): network field must be slice not string
Mihomo expects network: ["tcp", "udp"] (array) for TrustTunnel
listeners. The frontend Select stored a single string ("tcp" or
"udp"), which copyConfigPassthrough emitted as network: "tcp"
(string). Mihomo rejected with: 'network' is not a slice.
Fix:
- Frontend: network Select changed to mode="multiple" (multi-select)
Storing as array, reading as array (backward compatible with string)
- Backend: TrustTunnelCompiler.Compile converts string network to
[]string{network} for legacy configs that still have a string
Official docs: network: ["tcp", "udp"] # http2+http3
fix(trusttunnel): network field must be slice not string
Mihomo expects network: ["tcp", "udp"] (array) for TrustTunnel
listeners. The frontend Select stored a single string ("tcp" or
"udp"), which copyConfigPassthrough emitted as network: "tcp"
(string). Mihomo rejected with: 'network' is not a slice.
Fix:
- Frontend: network Select changed to mode="multiple" (multi-select)
Storing as array, reading as array (backward compatible with string)
- Backend: TrustTunnelCompiler.Compile converts string network to
[]string{network} for legacy configs that still have a string
Official docs: network: ["tcp", "udp"] # http2+http3
fix(trusttunnel): network field must be slice not string
Mihomo expects network: ["tcp", "udp"] (array) for TrustTunnel
listeners. The frontend Select stored a single string ("tcp" or
"udp"), which copyConfigPassthrough emitted as network: "tcp"
(string). Mihomo rejected with: 'network' is not a slice.
Fix:
- Frontend: network Select changed to mode="multiple" (multi-select)
Storing as array, reading as array (backward compatible with string)
- Backend: TrustTunnelCompiler.Compile converts string network to
[]string{network} for legacy configs that still have a string
Official docs: network: ["tcp", "udp"] # http2+http3
fix(trusttunnel): network field must be slice not string
Mihomo expects network: ["tcp", "udp"] (array) for TrustTunnel
listeners. The frontend Select stored a single string ("tcp" or
"udp"), which copyConfigPassthrough emitted as network: "tcp"
(string). Mihomo rejected with: 'network' is not a slice.
Fix:
- Frontend: network Select changed to mode="multiple" (multi-select)
Storing as array, reading as array (backward compatible with string)
- Backend: TrustTunnelCompiler.Compile converts string network to
[]string{network} for legacy configs that still have a string
Official docs: network: ["tcp", "udp"] # http2+http3
fix(trusttunnel): network field must be slice not string
Mihomo expects network: ["tcp", "udp"] (array) for TrustTunnel
listeners. The frontend Select stored a single string ("tcp" or
"udp"), which copyConfigPassthrough emitted as network: "tcp"
(string). Mihomo rejected with: 'network' is not a slice.
Fix:
- Frontend: network Select changed to mode="multiple" (multi-select)
Storing as array, reading as array (backward compatible with string)
- Backend: TrustTunnelCompiler.Compile converts string network to
[]string{network} for legacy configs that still have a string
Official docs: network: ["tcp", "udp"] # http2+http3
fix(trusttunnel): network field must be slice not string
Mihomo expects network: ["tcp", "udp"] (array) for TrustTunnel
listeners. The frontend Select stored a single string ("tcp" or
"udp"), which copyConfigPassthrough emitted as network: "tcp"
(string). Mihomo rejected with: 'network' is not a slice.
Fix:
- Frontend: network Select changed to mode="multiple" (multi-select)
Storing as array, reading as array (backward compatible with string)
- Backend: TrustTunnelCompiler.Compile converts string network to
[]string{network} for legacy configs that still have a string
Official docs: network: ["tcp", "udp"] # http2+http3
fix(trusttunnel): network field must be slice not string
Mihomo expects network: ["tcp", "udp"] (array) for TrustTunnel
listeners. The frontend Select stored a single string ("tcp" or
"udp"), which copyConfigPassthrough emitted as network: "tcp"
(string). Mihomo rejected with: 'network' is not a slice.
Fix:
- Frontend: network Select changed to mode="multiple" (multi-select)
Storing as array, reading as array (backward compatible with string)
- Backend: TrustTunnelCompiler.Compile converts string network to
[]string{network} for legacy configs that still have a string
Official docs: network: ["tcp", "udp"] # http2+http3
fix(trusttunnel): network field must be slice not string
Mihomo expects network: ["tcp", "udp"] (array) for TrustTunnel
listeners. The frontend Select stored a single string ("tcp" or
"udp"), which copyConfigPassthrough emitted as network: "tcp"
(string). Mihomo rejected with: 'network' is not a slice.
Fix:
- Frontend: network Select changed to mode="multiple" (multi-select)
Storing as array, reading as array (backward compatible with string)
- Backend: TrustTunnelCompiler.Compile converts string network to
[]string{network} for legacy configs that still have a string
Official docs: network: ["tcp", "udp"] # http2+http3
fix(trusttunnel): network field must be slice not string
Mihomo expects network: ["tcp", "udp"] (array) for TrustTunnel
listeners. The frontend Select stored a single string ("tcp" or
"udp"), which copyConfigPassthrough emitted as network: "tcp"
(string). Mihomo rejected with: 'network' is not a slice.
Fix:
- Frontend: network Select changed to mode="multiple" (multi-select)
Storing as array, reading as array (backward compatible with string)
- Backend: TrustTunnelCompiler.Compile converts string network to
[]string{network} for legacy configs that still have a string
Official docs: network: ["tcp", "udp"] # http2+http3
fix(trusttunnel): network field must be slice not string
Mihomo expects network: ["tcp", "udp"] (array) for TrustTunnel
listeners. The frontend Select stored a single string ("tcp" or
"udp"), which copyConfigPassthrough emitted as network: "tcp"
(string). Mihomo rejected with: 'network' is not a slice.
Fix:
- Frontend: network Select changed to mode="multiple" (multi-select)
Storing as array, reading as array (backward compatible with string)
- Backend: TrustTunnelCompiler.Compile converts string network to
[]string{network} for legacy configs that still have a string
Official docs: network: ["tcp", "udp"] # http2+http3
fix(trusttunnel): network field must be slice not string
Mihomo expects network: ["tcp", "udp"] (array) for TrustTunnel
listeners. The frontend Select stored a single string ("tcp" or
"udp"), which copyConfigPassthrough emitted as network: "tcp"
(string). Mihomo rejected with: 'network' is not a slice.
Fix:
- Frontend: network Select changed to mode="multiple" (multi-select)
Storing as array, reading as array (backward compatible with string)
- Backend: TrustTunnelCompiler.Compile converts string network to
[]string{network} for legacy configs that still have a string
Official docs: network: ["tcp", "udp"] # http2+http3
2026-08-31 14:22:14 +00:00
Z User 0e2d47d778 fix(protocol): XHTTP transport is VLESS-only in capabilities and UI
VMess/Trojan shared transportComponents() which listed XHTTP. Split a
VLESS-only transportComponentsWithXHTTP(); hide XHTTP radio/hint for
other protocols and refuse to emit xhttp-config unless protocol is vless.
fix(protocol): XHTTP transport is VLESS-only in capabilities and UI
VMess/Trojan shared transportComponents() which listed XHTTP. Split a
VLESS-only transportComponentsWithXHTTP(); hide XHTTP radio/hint for
other protocols and refuse to emit xhttp-config unless protocol is vless.
fix(protocol): XHTTP transport is VLESS-only in capabilities and UI
VMess/Trojan shared transportComponents() which listed XHTTP. Split a
VLESS-only transportComponentsWithXHTTP(); hide XHTTP radio/hint for
other protocols and refuse to emit xhttp-config unless protocol is vless.
fix(protocol): XHTTP transport is VLESS-only in capabilities and UI
VMess/Trojan shared transportComponents() which listed XHTTP. Split a
VLESS-only transportComponentsWithXHTTP(); hide XHTTP radio/hint for
other protocols and refuse to emit xhttp-config unless protocol is vless.
fix(protocol): XHTTP transport is VLESS-only in capabilities and UI
VMess/Trojan shared transportComponents() which listed XHTTP. Split a
VLESS-only transportComponentsWithXHTTP(); hide XHTTP radio/hint for
other protocols and refuse to emit xhttp-config unless protocol is vless.
fix(protocol): XHTTP transport is VLESS-only in capabilities and UI
VMess/Trojan shared transportComponents() which listed XHTTP. Split a
VLESS-only transportComponentsWithXHTTP(); hide XHTTP radio/hint for
other protocols and refuse to emit xhttp-config unless protocol is vless.
fix(protocol): XHTTP transport is VLESS-only in capabilities and UI
VMess/Trojan shared transportComponents() which listed XHTTP. Split a
VLESS-only transportComponentsWithXHTTP(); hide XHTTP radio/hint for
other protocols and refuse to emit xhttp-config unless protocol is vless.
fix(protocol): XHTTP transport is VLESS-only in capabilities and UI
VMess/Trojan shared transportComponents() which listed XHTTP. Split a
VLESS-only transportComponentsWithXHTTP(); hide XHTTP radio/hint for
other protocols and refuse to emit xhttp-config unless protocol is vless.
fix(protocol): XHTTP transport is VLESS-only in capabilities and UI
VMess/Trojan shared transportComponents() which listed XHTTP. Split a
VLESS-only transportComponentsWithXHTTP(); hide XHTTP radio/hint for
other protocols and refuse to emit xhttp-config unless protocol is vless.
fix(protocol): XHTTP transport is VLESS-only in capabilities and UI
VMess/Trojan shared transportComponents() which listed XHTTP. Split a
VLESS-only transportComponentsWithXHTTP(); hide XHTTP radio/hint for
other protocols and refuse to emit xhttp-config unless protocol is vless.
fix(protocol): XHTTP transport is VLESS-only in capabilities and UI
VMess/Trojan shared transportComponents() which listed XHTTP. Split a
VLESS-only transportComponentsWithXHTTP(); hide XHTTP radio/hint for
other protocols and refuse to emit xhttp-config unless protocol is vless.
fix(protocol): XHTTP transport is VLESS-only in capabilities and UI
VMess/Trojan shared transportComponents() which listed XHTTP. Split a
VLESS-only transportComponentsWithXHTTP(); hide XHTTP radio/hint for
other protocols and refuse to emit xhttp-config unless protocol is vless.
2026-08-31 07:28:58 +00:00
Z User 214605d9c8 fix(ui/protocol): P1 always-TLS UX, P2 wrapper sanitize, P3 ShadowQUIC/tlsmirror
- Hy2/TUIC/AnyTLS/TrustTunnel: no Security=None; always show cert with auto hint
- Optional protocols: cert only when security_layer=tls
- Do not emit incomplete shadow-tls/res-tls/jls/jls-upstream/tlsmirror
- Sanitize same blocks on save and config generation
- ShadowQUIC default congestion-controller=cubic
- VMess minimal tlsmirror-config (dest + primary-key)
fix(ui/protocol): P1 always-TLS UX, P2 wrapper sanitize, P3 ShadowQUIC/tlsmirror
- Hy2/TUIC/AnyTLS/TrustTunnel: no Security=None; always show cert with auto hint
- Optional protocols: cert only when security_layer=tls
- Do not emit incomplete shadow-tls/res-tls/jls/jls-upstream/tlsmirror
- Sanitize same blocks on save and config generation
- ShadowQUIC default congestion-controller=cubic
- VMess minimal tlsmirror-config (dest + primary-key)
fix(ui/protocol): P1 always-TLS UX, P2 wrapper sanitize, P3 ShadowQUIC/tlsmirror
- Hy2/TUIC/AnyTLS/TrustTunnel: no Security=None; always show cert with auto hint
- Optional protocols: cert only when security_layer=tls
- Do not emit incomplete shadow-tls/res-tls/jls/jls-upstream/tlsmirror
- Sanitize same blocks on save and config generation
- ShadowQUIC default congestion-controller=cubic
- VMess minimal tlsmirror-config (dest + primary-key)
fix(ui/protocol): P1 always-TLS UX, P2 wrapper sanitize, P3 ShadowQUIC/tlsmirror
- Hy2/TUIC/AnyTLS/TrustTunnel: no Security=None; always show cert with auto hint
- Optional protocols: cert only when security_layer=tls
- Do not emit incomplete shadow-tls/res-tls/jls/jls-upstream/tlsmirror
- Sanitize same blocks on save and config generation
- ShadowQUIC default congestion-controller=cubic
- VMess minimal tlsmirror-config (dest + primary-key)
fix(ui/protocol): P1 always-TLS UX, P2 wrapper sanitize, P3 ShadowQUIC/tlsmirror
- Hy2/TUIC/AnyTLS/TrustTunnel: no Security=None; always show cert with auto hint
- Optional protocols: cert only when security_layer=tls
- Do not emit incomplete shadow-tls/res-tls/jls/jls-upstream/tlsmirror
- Sanitize same blocks on save and config generation
- ShadowQUIC default congestion-controller=cubic
- VMess minimal tlsmirror-config (dest + primary-key)
fix(ui/protocol): P1 always-TLS UX, P2 wrapper sanitize, P3 ShadowQUIC/tlsmirror
- Hy2/TUIC/AnyTLS/TrustTunnel: no Security=None; always show cert with auto hint
- Optional protocols: cert only when security_layer=tls
- Do not emit incomplete shadow-tls/res-tls/jls/jls-upstream/tlsmirror
- Sanitize same blocks on save and config generation
- ShadowQUIC default congestion-controller=cubic
- VMess minimal tlsmirror-config (dest + primary-key)
fix(ui/protocol): P1 always-TLS UX, P2 wrapper sanitize, P3 ShadowQUIC/tlsmirror
- Hy2/TUIC/AnyTLS/TrustTunnel: no Security=None; always show cert with auto hint
- Optional protocols: cert only when security_layer=tls
- Do not emit incomplete shadow-tls/res-tls/jls/jls-upstream/tlsmirror
- Sanitize same blocks on save and config generation
- ShadowQUIC default congestion-controller=cubic
- VMess minimal tlsmirror-config (dest + primary-key)
fix(ui/protocol): P1 always-TLS UX, P2 wrapper sanitize, P3 ShadowQUIC/tlsmirror
- Hy2/TUIC/AnyTLS/TrustTunnel: no Security=None; always show cert with auto hint
- Optional protocols: cert only when security_layer=tls
- Do not emit incomplete shadow-tls/res-tls/jls/jls-upstream/tlsmirror
- Sanitize same blocks on save and config generation
- ShadowQUIC default congestion-controller=cubic
- VMess minimal tlsmirror-config (dest + primary-key)
fix(ui/protocol): P1 always-TLS UX, P2 wrapper sanitize, P3 ShadowQUIC/tlsmirror
- Hy2/TUIC/AnyTLS/TrustTunnel: no Security=None; always show cert with auto hint
- Optional protocols: cert only when security_layer=tls
- Do not emit incomplete shadow-tls/res-tls/jls/jls-upstream/tlsmirror
- Sanitize same blocks on save and config generation
- ShadowQUIC default congestion-controller=cubic
- VMess minimal tlsmirror-config (dest + primary-key)
fix(ui/protocol): P1 always-TLS UX, P2 wrapper sanitize, P3 ShadowQUIC/tlsmirror
- Hy2/TUIC/AnyTLS/TrustTunnel: no Security=None; always show cert with auto hint
- Optional protocols: cert only when security_layer=tls
- Do not emit incomplete shadow-tls/res-tls/jls/jls-upstream/tlsmirror
- Sanitize same blocks on save and config generation
- ShadowQUIC default congestion-controller=cubic
- VMess minimal tlsmirror-config (dest + primary-key)
fix(ui/protocol): P1 always-TLS UX, P2 wrapper sanitize, P3 ShadowQUIC/tlsmirror
- Hy2/TUIC/AnyTLS/TrustTunnel: no Security=None; always show cert with auto hint
- Optional protocols: cert only when security_layer=tls
- Do not emit incomplete shadow-tls/res-tls/jls/jls-upstream/tlsmirror
- Sanitize same blocks on save and config generation
- ShadowQUIC default congestion-controller=cubic
- VMess minimal tlsmirror-config (dest + primary-key)
fix(ui/protocol): P1 always-TLS UX, P2 wrapper sanitize, P3 ShadowQUIC/tlsmirror
- Hy2/TUIC/AnyTLS/TrustTunnel: no Security=None; always show cert with auto hint
- Optional protocols: cert only when security_layer=tls
- Do not emit incomplete shadow-tls/res-tls/jls/jls-upstream/tlsmirror
- Sanitize same blocks on save and config generation
- ShadowQUIC default congestion-controller=cubic
- VMess minimal tlsmirror-config (dest + primary-key)
2026-08-31 07:20:24 +00:00
Z User e589f9d414 fix(tuic): client uuid fallback, ALPN h3 defaults, real UUID autofill
TUIC v5 clients require uuid+password matching server users map keys.
Fill uuid from username when panel UUID is empty, default alpn=h3 and
congestion-controller=bbr, auto skip-cert-verify for panel certs, and
stop using the non-UUID key "default" in autofill.
fix(tuic): client uuid fallback, ALPN h3 defaults, real UUID autofill
TUIC v5 clients require uuid+password matching server users map keys.
Fill uuid from username when panel UUID is empty, default alpn=h3 and
congestion-controller=bbr, auto skip-cert-verify for panel certs, and
stop using the non-UUID key "default" in autofill.
fix(tuic): client uuid fallback, ALPN h3 defaults, real UUID autofill
TUIC v5 clients require uuid+password matching server users map keys.
Fill uuid from username when panel UUID is empty, default alpn=h3 and
congestion-controller=bbr, auto skip-cert-verify for panel certs, and
stop using the non-UUID key "default" in autofill.
fix(tuic): client uuid fallback, ALPN h3 defaults, real UUID autofill
TUIC v5 clients require uuid+password matching server users map keys.
Fill uuid from username when panel UUID is empty, default alpn=h3 and
congestion-controller=bbr, auto skip-cert-verify for panel certs, and
stop using the non-UUID key "default" in autofill.
fix(tuic): client uuid fallback, ALPN h3 defaults, real UUID autofill
TUIC v5 clients require uuid+password matching server users map keys.
Fill uuid from username when panel UUID is empty, default alpn=h3 and
congestion-controller=bbr, auto skip-cert-verify for panel certs, and
stop using the non-UUID key "default" in autofill.
fix(tuic): client uuid fallback, ALPN h3 defaults, real UUID autofill
TUIC v5 clients require uuid+password matching server users map keys.
Fill uuid from username when panel UUID is empty, default alpn=h3 and
congestion-controller=bbr, auto skip-cert-verify for panel certs, and
stop using the non-UUID key "default" in autofill.
fix(tuic): client uuid fallback, ALPN h3 defaults, real UUID autofill
TUIC v5 clients require uuid+password matching server users map keys.
Fill uuid from username when panel UUID is empty, default alpn=h3 and
congestion-controller=bbr, auto skip-cert-verify for panel certs, and
stop using the non-UUID key "default" in autofill.
fix(tuic): client uuid fallback, ALPN h3 defaults, real UUID autofill
TUIC v5 clients require uuid+password matching server users map keys.
Fill uuid from username when panel UUID is empty, default alpn=h3 and
congestion-controller=bbr, auto skip-cert-verify for panel certs, and
stop using the non-UUID key "default" in autofill.
fix(tuic): client uuid fallback, ALPN h3 defaults, real UUID autofill
TUIC v5 clients require uuid+password matching server users map keys.
Fill uuid from username when panel UUID is empty, default alpn=h3 and
congestion-controller=bbr, auto skip-cert-verify for panel certs, and
stop using the non-UUID key "default" in autofill.
fix(tuic): client uuid fallback, ALPN h3 defaults, real UUID autofill
TUIC v5 clients require uuid+password matching server users map keys.
Fill uuid from username when panel UUID is empty, default alpn=h3 and
congestion-controller=bbr, auto skip-cert-verify for panel certs, and
stop using the non-UUID key "default" in autofill.
fix(tuic): client uuid fallback, ALPN h3 defaults, real UUID autofill
TUIC v5 clients require uuid+password matching server users map keys.
Fill uuid from username when panel UUID is empty, default alpn=h3 and
congestion-controller=bbr, auto skip-cert-verify for panel certs, and
stop using the non-UUID key "default" in autofill.
fix(tuic): client uuid fallback, ALPN h3 defaults, real UUID autofill
TUIC v5 clients require uuid+password matching server users map keys.
Fill uuid from username when panel UUID is empty, default alpn=h3 and
congestion-controller=bbr, auto skip-cert-verify for panel certs, and
stop using the non-UUID key "default" in autofill.
2026-08-31 06:39:27 +00:00
Z User 913783b309 fix(critical): listener users empty when panel creds unavailable
ROOT CAUSE: asUsersArray/asUsersMap/asUsersMapUUID had a guard:
if hasCredState { return nil }
When a listener had ListenerUser bindings (hasCredState=true) but the
panel credentials were empty (decrypt failure, user inactive, etc.),
the compiler returned nil users → Mihomo config had no users field →
validation failed: 'unset fields: users'.
This caused two symptoms:
1. Subscription returns 'no exportable proxies for user'
2. Binding nodes fails: 'Mihomo configuration could not be updated:
validate Mihomo configuration: listener 1 has unset fields: users'
Fix: removed the hasCredState guard in all three functions. When panel
credentials are empty, fall back to the listener config's users field.
This is safe because:
- Config users were validated by the listener schema
- Config users were autofilled (password/UUID generated) on create
- Panel users take precedence when available (fromCreds checked first)
- Config users are a safety net for decrypt failures, inactive users
The hasCredState parameter is kept in the signature for API compat
but no longer affects the fallback logic.
fix(critical): listener users empty when panel creds unavailable
ROOT CAUSE: asUsersArray/asUsersMap/asUsersMapUUID had a guard:
if hasCredState { return nil }
When a listener had ListenerUser bindings (hasCredState=true) but the
panel credentials were empty (decrypt failure, user inactive, etc.),
the compiler returned nil users → Mihomo config had no users field →
validation failed: 'unset fields: users'.
This caused two symptoms:
1. Subscription returns 'no exportable proxies for user'
2. Binding nodes fails: 'Mihomo configuration could not be updated:
validate Mihomo configuration: listener 1 has unset fields: users'
Fix: removed the hasCredState guard in all three functions. When panel
credentials are empty, fall back to the listener config's users field.
This is safe because:
- Config users were validated by the listener schema
- Config users were autofilled (password/UUID generated) on create
- Panel users take precedence when available (fromCreds checked first)
- Config users are a safety net for decrypt failures, inactive users
The hasCredState parameter is kept in the signature for API compat
but no longer affects the fallback logic.
fix(critical): listener users empty when panel creds unavailable
ROOT CAUSE: asUsersArray/asUsersMap/asUsersMapUUID had a guard:
if hasCredState { return nil }
When a listener had ListenerUser bindings (hasCredState=true) but the
panel credentials were empty (decrypt failure, user inactive, etc.),
the compiler returned nil users → Mihomo config had no users field →
validation failed: 'unset fields: users'.
This caused two symptoms:
1. Subscription returns 'no exportable proxies for user'
2. Binding nodes fails: 'Mihomo configuration could not be updated:
validate Mihomo configuration: listener 1 has unset fields: users'
Fix: removed the hasCredState guard in all three functions. When panel
credentials are empty, fall back to the listener config's users field.
This is safe because:
- Config users were validated by the listener schema
- Config users were autofilled (password/UUID generated) on create
- Panel users take precedence when available (fromCreds checked first)
- Config users are a safety net for decrypt failures, inactive users
The hasCredState parameter is kept in the signature for API compat
but no longer affects the fallback logic.
fix(critical): listener users empty when panel creds unavailable
ROOT CAUSE: asUsersArray/asUsersMap/asUsersMapUUID had a guard:
if hasCredState { return nil }
When a listener had ListenerUser bindings (hasCredState=true) but the
panel credentials were empty (decrypt failure, user inactive, etc.),
the compiler returned nil users → Mihomo config had no users field →
validation failed: 'unset fields: users'.
This caused two symptoms:
1. Subscription returns 'no exportable proxies for user'
2. Binding nodes fails: 'Mihomo configuration could not be updated:
validate Mihomo configuration: listener 1 has unset fields: users'
Fix: removed the hasCredState guard in all three functions. When panel
credentials are empty, fall back to the listener config's users field.
This is safe because:
- Config users were validated by the listener schema
- Config users were autofilled (password/UUID generated) on create
- Panel users take precedence when available (fromCreds checked first)
- Config users are a safety net for decrypt failures, inactive users
The hasCredState parameter is kept in the signature for API compat
but no longer affects the fallback logic.
fix(critical): listener users empty when panel creds unavailable
ROOT CAUSE: asUsersArray/asUsersMap/asUsersMapUUID had a guard:
if hasCredState { return nil }
When a listener had ListenerUser bindings (hasCredState=true) but the
panel credentials were empty (decrypt failure, user inactive, etc.),
the compiler returned nil users → Mihomo config had no users field →
validation failed: 'unset fields: users'.
This caused two symptoms:
1. Subscription returns 'no exportable proxies for user'
2. Binding nodes fails: 'Mihomo configuration could not be updated:
validate Mihomo configuration: listener 1 has unset fields: users'
Fix: removed the hasCredState guard in all three functions. When panel
credentials are empty, fall back to the listener config's users field.
This is safe because:
- Config users were validated by the listener schema
- Config users were autofilled (password/UUID generated) on create
- Panel users take precedence when available (fromCreds checked first)
- Config users are a safety net for decrypt failures, inactive users
The hasCredState parameter is kept in the signature for API compat
but no longer affects the fallback logic.
fix(critical): listener users empty when panel creds unavailable
ROOT CAUSE: asUsersArray/asUsersMap/asUsersMapUUID had a guard:
if hasCredState { return nil }
When a listener had ListenerUser bindings (hasCredState=true) but the
panel credentials were empty (decrypt failure, user inactive, etc.),
the compiler returned nil users → Mihomo config had no users field →
validation failed: 'unset fields: users'.
This caused two symptoms:
1. Subscription returns 'no exportable proxies for user'
2. Binding nodes fails: 'Mihomo configuration could not be updated:
validate Mihomo configuration: listener 1 has unset fields: users'
Fix: removed the hasCredState guard in all three functions. When panel
credentials are empty, fall back to the listener config's users field.
This is safe because:
- Config users were validated by the listener schema
- Config users were autofilled (password/UUID generated) on create
- Panel users take precedence when available (fromCreds checked first)
- Config users are a safety net for decrypt failures, inactive users
The hasCredState parameter is kept in the signature for API compat
but no longer affects the fallback logic.
fix(critical): listener users empty when panel creds unavailable
ROOT CAUSE: asUsersArray/asUsersMap/asUsersMapUUID had a guard:
if hasCredState { return nil }
When a listener had ListenerUser bindings (hasCredState=true) but the
panel credentials were empty (decrypt failure, user inactive, etc.),
the compiler returned nil users → Mihomo config had no users field →
validation failed: 'unset fields: users'.
This caused two symptoms:
1. Subscription returns 'no exportable proxies for user'
2. Binding nodes fails: 'Mihomo configuration could not be updated:
validate Mihomo configuration: listener 1 has unset fields: users'
Fix: removed the hasCredState guard in all three functions. When panel
credentials are empty, fall back to the listener config's users field.
This is safe because:
- Config users were validated by the listener schema
- Config users were autofilled (password/UUID generated) on create
- Panel users take precedence when available (fromCreds checked first)
- Config users are a safety net for decrypt failures, inactive users
The hasCredState parameter is kept in the signature for API compat
but no longer affects the fallback logic.
fix(critical): listener users empty when panel creds unavailable
ROOT CAUSE: asUsersArray/asUsersMap/asUsersMapUUID had a guard:
if hasCredState { return nil }
When a listener had ListenerUser bindings (hasCredState=true) but the
panel credentials were empty (decrypt failure, user inactive, etc.),
the compiler returned nil users → Mihomo config had no users field →
validation failed: 'unset fields: users'.
This caused two symptoms:
1. Subscription returns 'no exportable proxies for user'
2. Binding nodes fails: 'Mihomo configuration could not be updated:
validate Mihomo configuration: listener 1 has unset fields: users'
Fix: removed the hasCredState guard in all three functions. When panel
credentials are empty, fall back to the listener config's users field.
This is safe because:
- Config users were validated by the listener schema
- Config users were autofilled (password/UUID generated) on create
- Panel users take precedence when available (fromCreds checked first)
- Config users are a safety net for decrypt failures, inactive users
The hasCredState parameter is kept in the signature for API compat
but no longer affects the fallback logic.
fix(critical): listener users empty when panel creds unavailable
ROOT CAUSE: asUsersArray/asUsersMap/asUsersMapUUID had a guard:
if hasCredState { return nil }
When a listener had ListenerUser bindings (hasCredState=true) but the
panel credentials were empty (decrypt failure, user inactive, etc.),
the compiler returned nil users → Mihomo config had no users field →
validation failed: 'unset fields: users'.
This caused two symptoms:
1. Subscription returns 'no exportable proxies for user'
2. Binding nodes fails: 'Mihomo configuration could not be updated:
validate Mihomo configuration: listener 1 has unset fields: users'
Fix: removed the hasCredState guard in all three functions. When panel
credentials are empty, fall back to the listener config's users field.
This is safe because:
- Config users were validated by the listener schema
- Config users were autofilled (password/UUID generated) on create
- Panel users take precedence when available (fromCreds checked first)
- Config users are a safety net for decrypt failures, inactive users
The hasCredState parameter is kept in the signature for API compat
but no longer affects the fallback logic.
fix(critical): listener users empty when panel creds unavailable
ROOT CAUSE: asUsersArray/asUsersMap/asUsersMapUUID had a guard:
if hasCredState { return nil }
When a listener had ListenerUser bindings (hasCredState=true) but the
panel credentials were empty (decrypt failure, user inactive, etc.),
the compiler returned nil users → Mihomo config had no users field →
validation failed: 'unset fields: users'.
This caused two symptoms:
1. Subscription returns 'no exportable proxies for user'
2. Binding nodes fails: 'Mihomo configuration could not be updated:
validate Mihomo configuration: listener 1 has unset fields: users'
Fix: removed the hasCredState guard in all three functions. When panel
credentials are empty, fall back to the listener config's users field.
This is safe because:
- Config users were validated by the listener schema
- Config users were autofilled (password/UUID generated) on create
- Panel users take precedence when available (fromCreds checked first)
- Config users are a safety net for decrypt failures, inactive users
The hasCredState parameter is kept in the signature for API compat
but no longer affects the fallback logic.
fix(critical): listener users empty when panel creds unavailable
ROOT CAUSE: asUsersArray/asUsersMap/asUsersMapUUID had a guard:
if hasCredState { return nil }
When a listener had ListenerUser bindings (hasCredState=true) but the
panel credentials were empty (decrypt failure, user inactive, etc.),
the compiler returned nil users → Mihomo config had no users field →
validation failed: 'unset fields: users'.
This caused two symptoms:
1. Subscription returns 'no exportable proxies for user'
2. Binding nodes fails: 'Mihomo configuration could not be updated:
validate Mihomo configuration: listener 1 has unset fields: users'
Fix: removed the hasCredState guard in all three functions. When panel
credentials are empty, fall back to the listener config's users field.
This is safe because:
- Config users were validated by the listener schema
- Config users were autofilled (password/UUID generated) on create
- Panel users take precedence when available (fromCreds checked first)
- Config users are a safety net for decrypt failures, inactive users
The hasCredState parameter is kept in the signature for API compat
but no longer affects the fallback logic.
fix(critical): listener users empty when panel creds unavailable
ROOT CAUSE: asUsersArray/asUsersMap/asUsersMapUUID had a guard:
if hasCredState { return nil }
When a listener had ListenerUser bindings (hasCredState=true) but the
panel credentials were empty (decrypt failure, user inactive, etc.),
the compiler returned nil users → Mihomo config had no users field →
validation failed: 'unset fields: users'.
This caused two symptoms:
1. Subscription returns 'no exportable proxies for user'
2. Binding nodes fails: 'Mihomo configuration could not be updated:
validate Mihomo configuration: listener 1 has unset fields: users'
Fix: removed the hasCredState guard in all three functions. When panel
credentials are empty, fall back to the listener config's users field.
This is safe because:
- Config users were validated by the listener schema
- Config users were autofilled (password/UUID generated) on create
- Panel users take precedence when available (fromCreds checked first)
- Config users are a safety net for decrypt failures, inactive users
The hasCredState parameter is kept in the signature for API compat
but no longer affects the fallback logic.
2026-08-31 03:27:04 +00:00
Z User c817650597 fix(config): P2+P3+P4 audit fixes — client config, schema, m-ui bridge
Comprehensive audit against official Mihomo docs (Meta-Docs-main).
This commit addresses all remaining P2 (Medium) and P3/P4 (Low)
findings, completing the full audit fix campaign.
== P2 Medium (client config gaps) ==
P2-1: VLESS native share URI missing security=tls for non-Reality TLS
share_modules.go BuildShare only set security=reality; plain TLS
had no security param (clients default to none=plaintext).
Added else-if: security=tls when Node.TLS && no Reality.
P2-2: m-ui VLESS URI emitted non-standard security=shadow-tls/res-tls/jls
mui/protocol/vless.go leaked wrapper types into URI. Fixed: map all
TLS wrappers (shadow-tls/res-tls/jls) to security=tls; reality stays
reality; none omitted. Wrapper detail preserved in client YAML.
P2-3: m-ui decodeHy2 dropped alpn — client YAML ALPN always empty
mui/bridge.go Added shared decodeALPN helper (handles []interface{},
[]string, bare string). Wired into decodeHy2/decodeVMess/decodeTrojan/
decodeVLESS. Added ALPN field to domain VLESSSpec/VMessSpec/TrojanSpec.
P2-4: m-ui classicClientProxy (VMess/Trojan) missing ALPN field
mui/protocol/classic_stream.go Added ALPN yaml field + populated
from node.VMess.ALPN / node.Trojan.ALPN.
P2-5: m-ui vlessClientProxy missing ALPN field
mui/protocol/vless.go Added ALPN yaml field + populated from
node.VLESS.ALPN.
P2-6: sing-box TUIC v4 token not handled
converter/singbox.go TUIC case only read uuid+password. Added token
reading ([]interface{}/[]string/string) → sing-box native token field;
falls back to uuid+password for v5.
P2-7: sing-box VLESS missing encryption mapping
converter/singbox.go Added p[encryption] → ob[encryption] when non-empty.
== P3 Low (schema completeness + client gaps) ==
P3-1: ResTLS restls-script not copied to client restls-opts
converter/client.go resTLSClientOptions now copies restls-script.
P3-2: JLS only exports first user — documented as design limitation
(per-credential JLS user matching requires explicit binding table;
single-JLS-user deployments are correct). Added doc-comment.
P3-3: WS ws-headers not in schema — Host header never exportable
Added ws-headers to top-level Fields for vmess/vless/trojan, aligning
with copyTransport which already reads src[ws-headers].
P3-4: VMess tlsmirror-config steps missing name/headers/wait-time field
Added 3 missing steps.* sub-fields to match tls.md 12-field list.
P3-5: VMess users not in NestedFields — documented as design choice
(map-form vs array-form shape difference would break map-form
validation). Added explanatory comment.
P3-6: Hysteria2 URI up/down inconsistent between rows vs map users
uri_builders.go First branch now reads up/down from listener config,
matching second branch.
P3-7: SS mux-option over-broad — removed 7 proxy-side sing-mux fields
(enable, protocol, max-connections, min-streams, max-streams,
statistic, only-tcp) from ALL 7 protocols with mux-option. Kept
padding + brutal.*/brutal-opts.* (listener-documented fields).
P3-8: m-ui bridge only supports 5/12 protocols — documented as follow-up
(requires implementing 7 protocol decoders; large feature).
P3-9: Three-tier fallback inconsistency — documented as follow-up
(design issue requiring output-contract unification).
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean (on all modified files)
fix(config): P2+P3+P4 audit fixes — client config, schema, m-ui bridge
Comprehensive audit against official Mihomo docs (Meta-Docs-main).
This commit addresses all remaining P2 (Medium) and P3/P4 (Low)
findings, completing the full audit fix campaign.
== P2 Medium (client config gaps) ==
P2-1: VLESS native share URI missing security=tls for non-Reality TLS
share_modules.go BuildShare only set security=reality; plain TLS
had no security param (clients default to none=plaintext).
Added else-if: security=tls when Node.TLS && no Reality.
P2-2: m-ui VLESS URI emitted non-standard security=shadow-tls/res-tls/jls
mui/protocol/vless.go leaked wrapper types into URI. Fixed: map all
TLS wrappers (shadow-tls/res-tls/jls) to security=tls; reality stays
reality; none omitted. Wrapper detail preserved in client YAML.
P2-3: m-ui decodeHy2 dropped alpn — client YAML ALPN always empty
mui/bridge.go Added shared decodeALPN helper (handles []interface{},
[]string, bare string). Wired into decodeHy2/decodeVMess/decodeTrojan/
decodeVLESS. Added ALPN field to domain VLESSSpec/VMessSpec/TrojanSpec.
P2-4: m-ui classicClientProxy (VMess/Trojan) missing ALPN field
mui/protocol/classic_stream.go Added ALPN yaml field + populated
from node.VMess.ALPN / node.Trojan.ALPN.
P2-5: m-ui vlessClientProxy missing ALPN field
mui/protocol/vless.go Added ALPN yaml field + populated from
node.VLESS.ALPN.
P2-6: sing-box TUIC v4 token not handled
converter/singbox.go TUIC case only read uuid+password. Added token
reading ([]interface{}/[]string/string) → sing-box native token field;
falls back to uuid+password for v5.
P2-7: sing-box VLESS missing encryption mapping
converter/singbox.go Added p[encryption] → ob[encryption] when non-empty.
== P3 Low (schema completeness + client gaps) ==
P3-1: ResTLS restls-script not copied to client restls-opts
converter/client.go resTLSClientOptions now copies restls-script.
P3-2: JLS only exports first user — documented as design limitation
(per-credential JLS user matching requires explicit binding table;
single-JLS-user deployments are correct). Added doc-comment.
P3-3: WS ws-headers not in schema — Host header never exportable
Added ws-headers to top-level Fields for vmess/vless/trojan, aligning
with copyTransport which already reads src[ws-headers].
P3-4: VMess tlsmirror-config steps missing name/headers/wait-time field
Added 3 missing steps.* sub-fields to match tls.md 12-field list.
P3-5: VMess users not in NestedFields — documented as design choice
(map-form vs array-form shape difference would break map-form
validation). Added explanatory comment.
P3-6: Hysteria2 URI up/down inconsistent between rows vs map users
uri_builders.go First branch now reads up/down from listener config,
matching second branch.
P3-7: SS mux-option over-broad — removed 7 proxy-side sing-mux fields
(enable, protocol, max-connections, min-streams, max-streams,
statistic, only-tcp) from ALL 7 protocols with mux-option. Kept
padding + brutal.*/brutal-opts.* (listener-documented fields).
P3-8: m-ui bridge only supports 5/12 protocols — documented as follow-up
(requires implementing 7 protocol decoders; large feature).
P3-9: Three-tier fallback inconsistency — documented as follow-up
(design issue requiring output-contract unification).
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean (on all modified files)
fix(config): P2+P3+P4 audit fixes — client config, schema, m-ui bridge
Comprehensive audit against official Mihomo docs (Meta-Docs-main).
This commit addresses all remaining P2 (Medium) and P3/P4 (Low)
findings, completing the full audit fix campaign.
== P2 Medium (client config gaps) ==
P2-1: VLESS native share URI missing security=tls for non-Reality TLS
share_modules.go BuildShare only set security=reality; plain TLS
had no security param (clients default to none=plaintext).
Added else-if: security=tls when Node.TLS && no Reality.
P2-2: m-ui VLESS URI emitted non-standard security=shadow-tls/res-tls/jls
mui/protocol/vless.go leaked wrapper types into URI. Fixed: map all
TLS wrappers (shadow-tls/res-tls/jls) to security=tls; reality stays
reality; none omitted. Wrapper detail preserved in client YAML.
P2-3: m-ui decodeHy2 dropped alpn — client YAML ALPN always empty
mui/bridge.go Added shared decodeALPN helper (handles []interface{},
[]string, bare string). Wired into decodeHy2/decodeVMess/decodeTrojan/
decodeVLESS. Added ALPN field to domain VLESSSpec/VMessSpec/TrojanSpec.
P2-4: m-ui classicClientProxy (VMess/Trojan) missing ALPN field
mui/protocol/classic_stream.go Added ALPN yaml field + populated
from node.VMess.ALPN / node.Trojan.ALPN.
P2-5: m-ui vlessClientProxy missing ALPN field
mui/protocol/vless.go Added ALPN yaml field + populated from
node.VLESS.ALPN.
P2-6: sing-box TUIC v4 token not handled
converter/singbox.go TUIC case only read uuid+password. Added token
reading ([]interface{}/[]string/string) → sing-box native token field;
falls back to uuid+password for v5.
P2-7: sing-box VLESS missing encryption mapping
converter/singbox.go Added p[encryption] → ob[encryption] when non-empty.
== P3 Low (schema completeness + client gaps) ==
P3-1: ResTLS restls-script not copied to client restls-opts
converter/client.go resTLSClientOptions now copies restls-script.
P3-2: JLS only exports first user — documented as design limitation
(per-credential JLS user matching requires explicit binding table;
single-JLS-user deployments are correct). Added doc-comment.
P3-3: WS ws-headers not in schema — Host header never exportable
Added ws-headers to top-level Fields for vmess/vless/trojan, aligning
with copyTransport which already reads src[ws-headers].
P3-4: VMess tlsmirror-config steps missing name/headers/wait-time field
Added 3 missing steps.* sub-fields to match tls.md 12-field list.
P3-5: VMess users not in NestedFields — documented as design choice
(map-form vs array-form shape difference would break map-form
validation). Added explanatory comment.
P3-6: Hysteria2 URI up/down inconsistent between rows vs map users
uri_builders.go First branch now reads up/down from listener config,
matching second branch.
P3-7: SS mux-option over-broad — removed 7 proxy-side sing-mux fields
(enable, protocol, max-connections, min-streams, max-streams,
statistic, only-tcp) from ALL 7 protocols with mux-option. Kept
padding + brutal.*/brutal-opts.* (listener-documented fields).
P3-8: m-ui bridge only supports 5/12 protocols — documented as follow-up
(requires implementing 7 protocol decoders; large feature).
P3-9: Three-tier fallback inconsistency — documented as follow-up
(design issue requiring output-contract unification).
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean (on all modified files)
fix(config): P2+P3+P4 audit fixes — client config, schema, m-ui bridge
Comprehensive audit against official Mihomo docs (Meta-Docs-main).
This commit addresses all remaining P2 (Medium) and P3/P4 (Low)
findings, completing the full audit fix campaign.
== P2 Medium (client config gaps) ==
P2-1: VLESS native share URI missing security=tls for non-Reality TLS
share_modules.go BuildShare only set security=reality; plain TLS
had no security param (clients default to none=plaintext).
Added else-if: security=tls when Node.TLS && no Reality.
P2-2: m-ui VLESS URI emitted non-standard security=shadow-tls/res-tls/jls
mui/protocol/vless.go leaked wrapper types into URI. Fixed: map all
TLS wrappers (shadow-tls/res-tls/jls) to security=tls; reality stays
reality; none omitted. Wrapper detail preserved in client YAML.
P2-3: m-ui decodeHy2 dropped alpn — client YAML ALPN always empty
mui/bridge.go Added shared decodeALPN helper (handles []interface{},
[]string, bare string). Wired into decodeHy2/decodeVMess/decodeTrojan/
decodeVLESS. Added ALPN field to domain VLESSSpec/VMessSpec/TrojanSpec.
P2-4: m-ui classicClientProxy (VMess/Trojan) missing ALPN field
mui/protocol/classic_stream.go Added ALPN yaml field + populated
from node.VMess.ALPN / node.Trojan.ALPN.
P2-5: m-ui vlessClientProxy missing ALPN field
mui/protocol/vless.go Added ALPN yaml field + populated from
node.VLESS.ALPN.
P2-6: sing-box TUIC v4 token not handled
converter/singbox.go TUIC case only read uuid+password. Added token
reading ([]interface{}/[]string/string) → sing-box native token field;
falls back to uuid+password for v5.
P2-7: sing-box VLESS missing encryption mapping
converter/singbox.go Added p[encryption] → ob[encryption] when non-empty.
== P3 Low (schema completeness + client gaps) ==
P3-1: ResTLS restls-script not copied to client restls-opts
converter/client.go resTLSClientOptions now copies restls-script.
P3-2: JLS only exports first user — documented as design limitation
(per-credential JLS user matching requires explicit binding table;
single-JLS-user deployments are correct). Added doc-comment.
P3-3: WS ws-headers not in schema — Host header never exportable
Added ws-headers to top-level Fields for vmess/vless/trojan, aligning
with copyTransport which already reads src[ws-headers].
P3-4: VMess tlsmirror-config steps missing name/headers/wait-time field
Added 3 missing steps.* sub-fields to match tls.md 12-field list.
P3-5: VMess users not in NestedFields — documented as design choice
(map-form vs array-form shape difference would break map-form
validation). Added explanatory comment.
P3-6: Hysteria2 URI up/down inconsistent between rows vs map users
uri_builders.go First branch now reads up/down from listener config,
matching second branch.
P3-7: SS mux-option over-broad — removed 7 proxy-side sing-mux fields
(enable, protocol, max-connections, min-streams, max-streams,
statistic, only-tcp) from ALL 7 protocols with mux-option. Kept
padding + brutal.*/brutal-opts.* (listener-documented fields).
P3-8: m-ui bridge only supports 5/12 protocols — documented as follow-up
(requires implementing 7 protocol decoders; large feature).
P3-9: Three-tier fallback inconsistency — documented as follow-up
(design issue requiring output-contract unification).
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean (on all modified files)
fix(config): P2+P3+P4 audit fixes — client config, schema, m-ui bridge
Comprehensive audit against official Mihomo docs (Meta-Docs-main).
This commit addresses all remaining P2 (Medium) and P3/P4 (Low)
findings, completing the full audit fix campaign.
== P2 Medium (client config gaps) ==
P2-1: VLESS native share URI missing security=tls for non-Reality TLS
share_modules.go BuildShare only set security=reality; plain TLS
had no security param (clients default to none=plaintext).
Added else-if: security=tls when Node.TLS && no Reality.
P2-2: m-ui VLESS URI emitted non-standard security=shadow-tls/res-tls/jls
mui/protocol/vless.go leaked wrapper types into URI. Fixed: map all
TLS wrappers (shadow-tls/res-tls/jls) to security=tls; reality stays
reality; none omitted. Wrapper detail preserved in client YAML.
P2-3: m-ui decodeHy2 dropped alpn — client YAML ALPN always empty
mui/bridge.go Added shared decodeALPN helper (handles []interface{},
[]string, bare string). Wired into decodeHy2/decodeVMess/decodeTrojan/
decodeVLESS. Added ALPN field to domain VLESSSpec/VMessSpec/TrojanSpec.
P2-4: m-ui classicClientProxy (VMess/Trojan) missing ALPN field
mui/protocol/classic_stream.go Added ALPN yaml field + populated
from node.VMess.ALPN / node.Trojan.ALPN.
P2-5: m-ui vlessClientProxy missing ALPN field
mui/protocol/vless.go Added ALPN yaml field + populated from
node.VLESS.ALPN.
P2-6: sing-box TUIC v4 token not handled
converter/singbox.go TUIC case only read uuid+password. Added token
reading ([]interface{}/[]string/string) → sing-box native token field;
falls back to uuid+password for v5.
P2-7: sing-box VLESS missing encryption mapping
converter/singbox.go Added p[encryption] → ob[encryption] when non-empty.
== P3 Low (schema completeness + client gaps) ==
P3-1: ResTLS restls-script not copied to client restls-opts
converter/client.go resTLSClientOptions now copies restls-script.
P3-2: JLS only exports first user — documented as design limitation
(per-credential JLS user matching requires explicit binding table;
single-JLS-user deployments are correct). Added doc-comment.
P3-3: WS ws-headers not in schema — Host header never exportable
Added ws-headers to top-level Fields for vmess/vless/trojan, aligning
with copyTransport which already reads src[ws-headers].
P3-4: VMess tlsmirror-config steps missing name/headers/wait-time field
Added 3 missing steps.* sub-fields to match tls.md 12-field list.
P3-5: VMess users not in NestedFields — documented as design choice
(map-form vs array-form shape difference would break map-form
validation). Added explanatory comment.
P3-6: Hysteria2 URI up/down inconsistent between rows vs map users
uri_builders.go First branch now reads up/down from listener config,
matching second branch.
P3-7: SS mux-option over-broad — removed 7 proxy-side sing-mux fields
(enable, protocol, max-connections, min-streams, max-streams,
statistic, only-tcp) from ALL 7 protocols with mux-option. Kept
padding + brutal.*/brutal-opts.* (listener-documented fields).
P3-8: m-ui bridge only supports 5/12 protocols — documented as follow-up
(requires implementing 7 protocol decoders; large feature).
P3-9: Three-tier fallback inconsistency — documented as follow-up
(design issue requiring output-contract unification).
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean (on all modified files)
fix(config): P2+P3+P4 audit fixes — client config, schema, m-ui bridge
Comprehensive audit against official Mihomo docs (Meta-Docs-main).
This commit addresses all remaining P2 (Medium) and P3/P4 (Low)
findings, completing the full audit fix campaign.
== P2 Medium (client config gaps) ==
P2-1: VLESS native share URI missing security=tls for non-Reality TLS
share_modules.go BuildShare only set security=reality; plain TLS
had no security param (clients default to none=plaintext).
Added else-if: security=tls when Node.TLS && no Reality.
P2-2: m-ui VLESS URI emitted non-standard security=shadow-tls/res-tls/jls
mui/protocol/vless.go leaked wrapper types into URI. Fixed: map all
TLS wrappers (shadow-tls/res-tls/jls) to security=tls; reality stays
reality; none omitted. Wrapper detail preserved in client YAML.
P2-3: m-ui decodeHy2 dropped alpn — client YAML ALPN always empty
mui/bridge.go Added shared decodeALPN helper (handles []interface{},
[]string, bare string). Wired into decodeHy2/decodeVMess/decodeTrojan/
decodeVLESS. Added ALPN field to domain VLESSSpec/VMessSpec/TrojanSpec.
P2-4: m-ui classicClientProxy (VMess/Trojan) missing ALPN field
mui/protocol/classic_stream.go Added ALPN yaml field + populated
from node.VMess.ALPN / node.Trojan.ALPN.
P2-5: m-ui vlessClientProxy missing ALPN field
mui/protocol/vless.go Added ALPN yaml field + populated from
node.VLESS.ALPN.
P2-6: sing-box TUIC v4 token not handled
converter/singbox.go TUIC case only read uuid+password. Added token
reading ([]interface{}/[]string/string) → sing-box native token field;
falls back to uuid+password for v5.
P2-7: sing-box VLESS missing encryption mapping
converter/singbox.go Added p[encryption] → ob[encryption] when non-empty.
== P3 Low (schema completeness + client gaps) ==
P3-1: ResTLS restls-script not copied to client restls-opts
converter/client.go resTLSClientOptions now copies restls-script.
P3-2: JLS only exports first user — documented as design limitation
(per-credential JLS user matching requires explicit binding table;
single-JLS-user deployments are correct). Added doc-comment.
P3-3: WS ws-headers not in schema — Host header never exportable
Added ws-headers to top-level Fields for vmess/vless/trojan, aligning
with copyTransport which already reads src[ws-headers].
P3-4: VMess tlsmirror-config steps missing name/headers/wait-time field
Added 3 missing steps.* sub-fields to match tls.md 12-field list.
P3-5: VMess users not in NestedFields — documented as design choice
(map-form vs array-form shape difference would break map-form
validation). Added explanatory comment.
P3-6: Hysteria2 URI up/down inconsistent between rows vs map users
uri_builders.go First branch now reads up/down from listener config,
matching second branch.
P3-7: SS mux-option over-broad — removed 7 proxy-side sing-mux fields
(enable, protocol, max-connections, min-streams, max-streams,
statistic, only-tcp) from ALL 7 protocols with mux-option. Kept
padding + brutal.*/brutal-opts.* (listener-documented fields).
P3-8: m-ui bridge only supports 5/12 protocols — documented as follow-up
(requires implementing 7 protocol decoders; large feature).
P3-9: Three-tier fallback inconsistency — documented as follow-up
(design issue requiring output-contract unification).
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean (on all modified files)
fix(config): P2+P3+P4 audit fixes — client config, schema, m-ui bridge
Comprehensive audit against official Mihomo docs (Meta-Docs-main).
This commit addresses all remaining P2 (Medium) and P3/P4 (Low)
findings, completing the full audit fix campaign.
== P2 Medium (client config gaps) ==
P2-1: VLESS native share URI missing security=tls for non-Reality TLS
share_modules.go BuildShare only set security=reality; plain TLS
had no security param (clients default to none=plaintext).
Added else-if: security=tls when Node.TLS && no Reality.
P2-2: m-ui VLESS URI emitted non-standard security=shadow-tls/res-tls/jls
mui/protocol/vless.go leaked wrapper types into URI. Fixed: map all
TLS wrappers (shadow-tls/res-tls/jls) to security=tls; reality stays
reality; none omitted. Wrapper detail preserved in client YAML.
P2-3: m-ui decodeHy2 dropped alpn — client YAML ALPN always empty
mui/bridge.go Added shared decodeALPN helper (handles []interface{},
[]string, bare string). Wired into decodeHy2/decodeVMess/decodeTrojan/
decodeVLESS. Added ALPN field to domain VLESSSpec/VMessSpec/TrojanSpec.
P2-4: m-ui classicClientProxy (VMess/Trojan) missing ALPN field
mui/protocol/classic_stream.go Added ALPN yaml field + populated
from node.VMess.ALPN / node.Trojan.ALPN.
P2-5: m-ui vlessClientProxy missing ALPN field
mui/protocol/vless.go Added ALPN yaml field + populated from
node.VLESS.ALPN.
P2-6: sing-box TUIC v4 token not handled
converter/singbox.go TUIC case only read uuid+password. Added token
reading ([]interface{}/[]string/string) → sing-box native token field;
falls back to uuid+password for v5.
P2-7: sing-box VLESS missing encryption mapping
converter/singbox.go Added p[encryption] → ob[encryption] when non-empty.
== P3 Low (schema completeness + client gaps) ==
P3-1: ResTLS restls-script not copied to client restls-opts
converter/client.go resTLSClientOptions now copies restls-script.
P3-2: JLS only exports first user — documented as design limitation
(per-credential JLS user matching requires explicit binding table;
single-JLS-user deployments are correct). Added doc-comment.
P3-3: WS ws-headers not in schema — Host header never exportable
Added ws-headers to top-level Fields for vmess/vless/trojan, aligning
with copyTransport which already reads src[ws-headers].
P3-4: VMess tlsmirror-config steps missing name/headers/wait-time field
Added 3 missing steps.* sub-fields to match tls.md 12-field list.
P3-5: VMess users not in NestedFields — documented as design choice
(map-form vs array-form shape difference would break map-form
validation). Added explanatory comment.
P3-6: Hysteria2 URI up/down inconsistent between rows vs map users
uri_builders.go First branch now reads up/down from listener config,
matching second branch.
P3-7: SS mux-option over-broad — removed 7 proxy-side sing-mux fields
(enable, protocol, max-connections, min-streams, max-streams,
statistic, only-tcp) from ALL 7 protocols with mux-option. Kept
padding + brutal.*/brutal-opts.* (listener-documented fields).
P3-8: m-ui bridge only supports 5/12 protocols — documented as follow-up
(requires implementing 7 protocol decoders; large feature).
P3-9: Three-tier fallback inconsistency — documented as follow-up
(design issue requiring output-contract unification).
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean (on all modified files)
fix(config): P2+P3+P4 audit fixes — client config, schema, m-ui bridge
Comprehensive audit against official Mihomo docs (Meta-Docs-main).
This commit addresses all remaining P2 (Medium) and P3/P4 (Low)
findings, completing the full audit fix campaign.
== P2 Medium (client config gaps) ==
P2-1: VLESS native share URI missing security=tls for non-Reality TLS
share_modules.go BuildShare only set security=reality; plain TLS
had no security param (clients default to none=plaintext).
Added else-if: security=tls when Node.TLS && no Reality.
P2-2: m-ui VLESS URI emitted non-standard security=shadow-tls/res-tls/jls
mui/protocol/vless.go leaked wrapper types into URI. Fixed: map all
TLS wrappers (shadow-tls/res-tls/jls) to security=tls; reality stays
reality; none omitted. Wrapper detail preserved in client YAML.
P2-3: m-ui decodeHy2 dropped alpn — client YAML ALPN always empty
mui/bridge.go Added shared decodeALPN helper (handles []interface{},
[]string, bare string). Wired into decodeHy2/decodeVMess/decodeTrojan/
decodeVLESS. Added ALPN field to domain VLESSSpec/VMessSpec/TrojanSpec.
P2-4: m-ui classicClientProxy (VMess/Trojan) missing ALPN field
mui/protocol/classic_stream.go Added ALPN yaml field + populated
from node.VMess.ALPN / node.Trojan.ALPN.
P2-5: m-ui vlessClientProxy missing ALPN field
mui/protocol/vless.go Added ALPN yaml field + populated from
node.VLESS.ALPN.
P2-6: sing-box TUIC v4 token not handled
converter/singbox.go TUIC case only read uuid+password. Added token
reading ([]interface{}/[]string/string) → sing-box native token field;
falls back to uuid+password for v5.
P2-7: sing-box VLESS missing encryption mapping
converter/singbox.go Added p[encryption] → ob[encryption] when non-empty.
== P3 Low (schema completeness + client gaps) ==
P3-1: ResTLS restls-script not copied to client restls-opts
converter/client.go resTLSClientOptions now copies restls-script.
P3-2: JLS only exports first user — documented as design limitation
(per-credential JLS user matching requires explicit binding table;
single-JLS-user deployments are correct). Added doc-comment.
P3-3: WS ws-headers not in schema — Host header never exportable
Added ws-headers to top-level Fields for vmess/vless/trojan, aligning
with copyTransport which already reads src[ws-headers].
P3-4: VMess tlsmirror-config steps missing name/headers/wait-time field
Added 3 missing steps.* sub-fields to match tls.md 12-field list.
P3-5: VMess users not in NestedFields — documented as design choice
(map-form vs array-form shape difference would break map-form
validation). Added explanatory comment.
P3-6: Hysteria2 URI up/down inconsistent between rows vs map users
uri_builders.go First branch now reads up/down from listener config,
matching second branch.
P3-7: SS mux-option over-broad — removed 7 proxy-side sing-mux fields
(enable, protocol, max-connections, min-streams, max-streams,
statistic, only-tcp) from ALL 7 protocols with mux-option. Kept
padding + brutal.*/brutal-opts.* (listener-documented fields).
P3-8: m-ui bridge only supports 5/12 protocols — documented as follow-up
(requires implementing 7 protocol decoders; large feature).
P3-9: Three-tier fallback inconsistency — documented as follow-up
(design issue requiring output-contract unification).
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean (on all modified files)
fix(config): P2+P3+P4 audit fixes — client config, schema, m-ui bridge
Comprehensive audit against official Mihomo docs (Meta-Docs-main).
This commit addresses all remaining P2 (Medium) and P3/P4 (Low)
findings, completing the full audit fix campaign.
== P2 Medium (client config gaps) ==
P2-1: VLESS native share URI missing security=tls for non-Reality TLS
share_modules.go BuildShare only set security=reality; plain TLS
had no security param (clients default to none=plaintext).
Added else-if: security=tls when Node.TLS && no Reality.
P2-2: m-ui VLESS URI emitted non-standard security=shadow-tls/res-tls/jls
mui/protocol/vless.go leaked wrapper types into URI. Fixed: map all
TLS wrappers (shadow-tls/res-tls/jls) to security=tls; reality stays
reality; none omitted. Wrapper detail preserved in client YAML.
P2-3: m-ui decodeHy2 dropped alpn — client YAML ALPN always empty
mui/bridge.go Added shared decodeALPN helper (handles []interface{},
[]string, bare string). Wired into decodeHy2/decodeVMess/decodeTrojan/
decodeVLESS. Added ALPN field to domain VLESSSpec/VMessSpec/TrojanSpec.
P2-4: m-ui classicClientProxy (VMess/Trojan) missing ALPN field
mui/protocol/classic_stream.go Added ALPN yaml field + populated
from node.VMess.ALPN / node.Trojan.ALPN.
P2-5: m-ui vlessClientProxy missing ALPN field
mui/protocol/vless.go Added ALPN yaml field + populated from
node.VLESS.ALPN.
P2-6: sing-box TUIC v4 token not handled
converter/singbox.go TUIC case only read uuid+password. Added token
reading ([]interface{}/[]string/string) → sing-box native token field;
falls back to uuid+password for v5.
P2-7: sing-box VLESS missing encryption mapping
converter/singbox.go Added p[encryption] → ob[encryption] when non-empty.
== P3 Low (schema completeness + client gaps) ==
P3-1: ResTLS restls-script not copied to client restls-opts
converter/client.go resTLSClientOptions now copies restls-script.
P3-2: JLS only exports first user — documented as design limitation
(per-credential JLS user matching requires explicit binding table;
single-JLS-user deployments are correct). Added doc-comment.
P3-3: WS ws-headers not in schema — Host header never exportable
Added ws-headers to top-level Fields for vmess/vless/trojan, aligning
with copyTransport which already reads src[ws-headers].
P3-4: VMess tlsmirror-config steps missing name/headers/wait-time field
Added 3 missing steps.* sub-fields to match tls.md 12-field list.
P3-5: VMess users not in NestedFields — documented as design choice
(map-form vs array-form shape difference would break map-form
validation). Added explanatory comment.
P3-6: Hysteria2 URI up/down inconsistent between rows vs map users
uri_builders.go First branch now reads up/down from listener config,
matching second branch.
P3-7: SS mux-option over-broad — removed 7 proxy-side sing-mux fields
(enable, protocol, max-connections, min-streams, max-streams,
statistic, only-tcp) from ALL 7 protocols with mux-option. Kept
padding + brutal.*/brutal-opts.* (listener-documented fields).
P3-8: m-ui bridge only supports 5/12 protocols — documented as follow-up
(requires implementing 7 protocol decoders; large feature).
P3-9: Three-tier fallback inconsistency — documented as follow-up
(design issue requiring output-contract unification).
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean (on all modified files)
fix(config): P2+P3+P4 audit fixes — client config, schema, m-ui bridge
Comprehensive audit against official Mihomo docs (Meta-Docs-main).
This commit addresses all remaining P2 (Medium) and P3/P4 (Low)
findings, completing the full audit fix campaign.
== P2 Medium (client config gaps) ==
P2-1: VLESS native share URI missing security=tls for non-Reality TLS
share_modules.go BuildShare only set security=reality; plain TLS
had no security param (clients default to none=plaintext).
Added else-if: security=tls when Node.TLS && no Reality.
P2-2: m-ui VLESS URI emitted non-standard security=shadow-tls/res-tls/jls
mui/protocol/vless.go leaked wrapper types into URI. Fixed: map all
TLS wrappers (shadow-tls/res-tls/jls) to security=tls; reality stays
reality; none omitted. Wrapper detail preserved in client YAML.
P2-3: m-ui decodeHy2 dropped alpn — client YAML ALPN always empty
mui/bridge.go Added shared decodeALPN helper (handles []interface{},
[]string, bare string). Wired into decodeHy2/decodeVMess/decodeTrojan/
decodeVLESS. Added ALPN field to domain VLESSSpec/VMessSpec/TrojanSpec.
P2-4: m-ui classicClientProxy (VMess/Trojan) missing ALPN field
mui/protocol/classic_stream.go Added ALPN yaml field + populated
from node.VMess.ALPN / node.Trojan.ALPN.
P2-5: m-ui vlessClientProxy missing ALPN field
mui/protocol/vless.go Added ALPN yaml field + populated from
node.VLESS.ALPN.
P2-6: sing-box TUIC v4 token not handled
converter/singbox.go TUIC case only read uuid+password. Added token
reading ([]interface{}/[]string/string) → sing-box native token field;
falls back to uuid+password for v5.
P2-7: sing-box VLESS missing encryption mapping
converter/singbox.go Added p[encryption] → ob[encryption] when non-empty.
== P3 Low (schema completeness + client gaps) ==
P3-1: ResTLS restls-script not copied to client restls-opts
converter/client.go resTLSClientOptions now copies restls-script.
P3-2: JLS only exports first user — documented as design limitation
(per-credential JLS user matching requires explicit binding table;
single-JLS-user deployments are correct). Added doc-comment.
P3-3: WS ws-headers not in schema — Host header never exportable
Added ws-headers to top-level Fields for vmess/vless/trojan, aligning
with copyTransport which already reads src[ws-headers].
P3-4: VMess tlsmirror-config steps missing name/headers/wait-time field
Added 3 missing steps.* sub-fields to match tls.md 12-field list.
P3-5: VMess users not in NestedFields — documented as design choice
(map-form vs array-form shape difference would break map-form
validation). Added explanatory comment.
P3-6: Hysteria2 URI up/down inconsistent between rows vs map users
uri_builders.go First branch now reads up/down from listener config,
matching second branch.
P3-7: SS mux-option over-broad — removed 7 proxy-side sing-mux fields
(enable, protocol, max-connections, min-streams, max-streams,
statistic, only-tcp) from ALL 7 protocols with mux-option. Kept
padding + brutal.*/brutal-opts.* (listener-documented fields).
P3-8: m-ui bridge only supports 5/12 protocols — documented as follow-up
(requires implementing 7 protocol decoders; large feature).
P3-9: Three-tier fallback inconsistency — documented as follow-up
(design issue requiring output-contract unification).
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean (on all modified files)
fix(config): P2+P3+P4 audit fixes — client config, schema, m-ui bridge
Comprehensive audit against official Mihomo docs (Meta-Docs-main).
This commit addresses all remaining P2 (Medium) and P3/P4 (Low)
findings, completing the full audit fix campaign.
== P2 Medium (client config gaps) ==
P2-1: VLESS native share URI missing security=tls for non-Reality TLS
share_modules.go BuildShare only set security=reality; plain TLS
had no security param (clients default to none=plaintext).
Added else-if: security=tls when Node.TLS && no Reality.
P2-2: m-ui VLESS URI emitted non-standard security=shadow-tls/res-tls/jls
mui/protocol/vless.go leaked wrapper types into URI. Fixed: map all
TLS wrappers (shadow-tls/res-tls/jls) to security=tls; reality stays
reality; none omitted. Wrapper detail preserved in client YAML.
P2-3: m-ui decodeHy2 dropped alpn — client YAML ALPN always empty
mui/bridge.go Added shared decodeALPN helper (handles []interface{},
[]string, bare string). Wired into decodeHy2/decodeVMess/decodeTrojan/
decodeVLESS. Added ALPN field to domain VLESSSpec/VMessSpec/TrojanSpec.
P2-4: m-ui classicClientProxy (VMess/Trojan) missing ALPN field
mui/protocol/classic_stream.go Added ALPN yaml field + populated
from node.VMess.ALPN / node.Trojan.ALPN.
P2-5: m-ui vlessClientProxy missing ALPN field
mui/protocol/vless.go Added ALPN yaml field + populated from
node.VLESS.ALPN.
P2-6: sing-box TUIC v4 token not handled
converter/singbox.go TUIC case only read uuid+password. Added token
reading ([]interface{}/[]string/string) → sing-box native token field;
falls back to uuid+password for v5.
P2-7: sing-box VLESS missing encryption mapping
converter/singbox.go Added p[encryption] → ob[encryption] when non-empty.
== P3 Low (schema completeness + client gaps) ==
P3-1: ResTLS restls-script not copied to client restls-opts
converter/client.go resTLSClientOptions now copies restls-script.
P3-2: JLS only exports first user — documented as design limitation
(per-credential JLS user matching requires explicit binding table;
single-JLS-user deployments are correct). Added doc-comment.
P3-3: WS ws-headers not in schema — Host header never exportable
Added ws-headers to top-level Fields for vmess/vless/trojan, aligning
with copyTransport which already reads src[ws-headers].
P3-4: VMess tlsmirror-config steps missing name/headers/wait-time field
Added 3 missing steps.* sub-fields to match tls.md 12-field list.
P3-5: VMess users not in NestedFields — documented as design choice
(map-form vs array-form shape difference would break map-form
validation). Added explanatory comment.
P3-6: Hysteria2 URI up/down inconsistent between rows vs map users
uri_builders.go First branch now reads up/down from listener config,
matching second branch.
P3-7: SS mux-option over-broad — removed 7 proxy-side sing-mux fields
(enable, protocol, max-connections, min-streams, max-streams,
statistic, only-tcp) from ALL 7 protocols with mux-option. Kept
padding + brutal.*/brutal-opts.* (listener-documented fields).
P3-8: m-ui bridge only supports 5/12 protocols — documented as follow-up
(requires implementing 7 protocol decoders; large feature).
P3-9: Three-tier fallback inconsistency — documented as follow-up
(design issue requiring output-contract unification).
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean (on all modified files)
fix(config): P2+P3+P4 audit fixes — client config, schema, m-ui bridge
Comprehensive audit against official Mihomo docs (Meta-Docs-main).
This commit addresses all remaining P2 (Medium) and P3/P4 (Low)
findings, completing the full audit fix campaign.
== P2 Medium (client config gaps) ==
P2-1: VLESS native share URI missing security=tls for non-Reality TLS
share_modules.go BuildShare only set security=reality; plain TLS
had no security param (clients default to none=plaintext).
Added else-if: security=tls when Node.TLS && no Reality.
P2-2: m-ui VLESS URI emitted non-standard security=shadow-tls/res-tls/jls
mui/protocol/vless.go leaked wrapper types into URI. Fixed: map all
TLS wrappers (shadow-tls/res-tls/jls) to security=tls; reality stays
reality; none omitted. Wrapper detail preserved in client YAML.
P2-3: m-ui decodeHy2 dropped alpn — client YAML ALPN always empty
mui/bridge.go Added shared decodeALPN helper (handles []interface{},
[]string, bare string). Wired into decodeHy2/decodeVMess/decodeTrojan/
decodeVLESS. Added ALPN field to domain VLESSSpec/VMessSpec/TrojanSpec.
P2-4: m-ui classicClientProxy (VMess/Trojan) missing ALPN field
mui/protocol/classic_stream.go Added ALPN yaml field + populated
from node.VMess.ALPN / node.Trojan.ALPN.
P2-5: m-ui vlessClientProxy missing ALPN field
mui/protocol/vless.go Added ALPN yaml field + populated from
node.VLESS.ALPN.
P2-6: sing-box TUIC v4 token not handled
converter/singbox.go TUIC case only read uuid+password. Added token
reading ([]interface{}/[]string/string) → sing-box native token field;
falls back to uuid+password for v5.
P2-7: sing-box VLESS missing encryption mapping
converter/singbox.go Added p[encryption] → ob[encryption] when non-empty.
== P3 Low (schema completeness + client gaps) ==
P3-1: ResTLS restls-script not copied to client restls-opts
converter/client.go resTLSClientOptions now copies restls-script.
P3-2: JLS only exports first user — documented as design limitation
(per-credential JLS user matching requires explicit binding table;
single-JLS-user deployments are correct). Added doc-comment.
P3-3: WS ws-headers not in schema — Host header never exportable
Added ws-headers to top-level Fields for vmess/vless/trojan, aligning
with copyTransport which already reads src[ws-headers].
P3-4: VMess tlsmirror-config steps missing name/headers/wait-time field
Added 3 missing steps.* sub-fields to match tls.md 12-field list.
P3-5: VMess users not in NestedFields — documented as design choice
(map-form vs array-form shape difference would break map-form
validation). Added explanatory comment.
P3-6: Hysteria2 URI up/down inconsistent between rows vs map users
uri_builders.go First branch now reads up/down from listener config,
matching second branch.
P3-7: SS mux-option over-broad — removed 7 proxy-side sing-mux fields
(enable, protocol, max-connections, min-streams, max-streams,
statistic, only-tcp) from ALL 7 protocols with mux-option. Kept
padding + brutal.*/brutal-opts.* (listener-documented fields).
P3-8: m-ui bridge only supports 5/12 protocols — documented as follow-up
(requires implementing 7 protocol decoders; large feature).
P3-9: Three-tier fallback inconsistency — documented as follow-up
(design issue requiring output-contract unification).
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean (on all modified files)
2026-08-30 04:13:26 +00:00
Z User a379c33159 fix(config): comprehensive audit vs official docs — client config + schema
Full audit against official Mihomo docs (Meta-Docs-main) found and
fixed 10 bugs across client config generation and schema completeness.
P0 Critical:
- VLESS client YAML missing network field (transport opts ignored)
- TUIC v4 token share broken (read as string, is array)
P1 High:
- SS base64 violates SIP002 (RawStd -> RawURL)
- VMess base64 inconsistency (RawStd -> Std padded)
- Hysteria2 server-only fields (masquerade/ca/ca-str) in client YAML
- sing-box VMess alter_id hardcoded to 0
- sing-box missing TLS insecure + alpn mapping
- VMess per-user alterId dropped when panel creds bound
P2 Medium:
- reality-config schema missing max-time-difference + proxy (vmess/vless/trojan)
- hysteria2 realm-opts schema missing sni
Verification: go build/vet/test all PASS; gofmt clean.
fix(config): comprehensive audit vs official docs — client config + schema
Full audit against official Mihomo docs (Meta-Docs-main) found and
fixed 10 bugs across client config generation and schema completeness.
P0 Critical:
- VLESS client YAML missing network field (transport opts ignored)
- TUIC v4 token share broken (read as string, is array)
P1 High:
- SS base64 violates SIP002 (RawStd -> RawURL)
- VMess base64 inconsistency (RawStd -> Std padded)
- Hysteria2 server-only fields (masquerade/ca/ca-str) in client YAML
- sing-box VMess alter_id hardcoded to 0
- sing-box missing TLS insecure + alpn mapping
- VMess per-user alterId dropped when panel creds bound
P2 Medium:
- reality-config schema missing max-time-difference + proxy (vmess/vless/trojan)
- hysteria2 realm-opts schema missing sni
Verification: go build/vet/test all PASS; gofmt clean.
fix(config): comprehensive audit vs official docs — client config + schema
Full audit against official Mihomo docs (Meta-Docs-main) found and
fixed 10 bugs across client config generation and schema completeness.
P0 Critical:
- VLESS client YAML missing network field (transport opts ignored)
- TUIC v4 token share broken (read as string, is array)
P1 High:
- SS base64 violates SIP002 (RawStd -> RawURL)
- VMess base64 inconsistency (RawStd -> Std padded)
- Hysteria2 server-only fields (masquerade/ca/ca-str) in client YAML
- sing-box VMess alter_id hardcoded to 0
- sing-box missing TLS insecure + alpn mapping
- VMess per-user alterId dropped when panel creds bound
P2 Medium:
- reality-config schema missing max-time-difference + proxy (vmess/vless/trojan)
- hysteria2 realm-opts schema missing sni
Verification: go build/vet/test all PASS; gofmt clean.
fix(config): comprehensive audit vs official docs — client config + schema
Full audit against official Mihomo docs (Meta-Docs-main) found and
fixed 10 bugs across client config generation and schema completeness.
P0 Critical:
- VLESS client YAML missing network field (transport opts ignored)
- TUIC v4 token share broken (read as string, is array)
P1 High:
- SS base64 violates SIP002 (RawStd -> RawURL)
- VMess base64 inconsistency (RawStd -> Std padded)
- Hysteria2 server-only fields (masquerade/ca/ca-str) in client YAML
- sing-box VMess alter_id hardcoded to 0
- sing-box missing TLS insecure + alpn mapping
- VMess per-user alterId dropped when panel creds bound
P2 Medium:
- reality-config schema missing max-time-difference + proxy (vmess/vless/trojan)
- hysteria2 realm-opts schema missing sni
Verification: go build/vet/test all PASS; gofmt clean.
fix(config): comprehensive audit vs official docs — client config + schema
Full audit against official Mihomo docs (Meta-Docs-main) found and
fixed 10 bugs across client config generation and schema completeness.
P0 Critical:
- VLESS client YAML missing network field (transport opts ignored)
- TUIC v4 token share broken (read as string, is array)
P1 High:
- SS base64 violates SIP002 (RawStd -> RawURL)
- VMess base64 inconsistency (RawStd -> Std padded)
- Hysteria2 server-only fields (masquerade/ca/ca-str) in client YAML
- sing-box VMess alter_id hardcoded to 0
- sing-box missing TLS insecure + alpn mapping
- VMess per-user alterId dropped when panel creds bound
P2 Medium:
- reality-config schema missing max-time-difference + proxy (vmess/vless/trojan)
- hysteria2 realm-opts schema missing sni
Verification: go build/vet/test all PASS; gofmt clean.
fix(config): comprehensive audit vs official docs — client config + schema
Full audit against official Mihomo docs (Meta-Docs-main) found and
fixed 10 bugs across client config generation and schema completeness.
P0 Critical:
- VLESS client YAML missing network field (transport opts ignored)
- TUIC v4 token share broken (read as string, is array)
P1 High:
- SS base64 violates SIP002 (RawStd -> RawURL)
- VMess base64 inconsistency (RawStd -> Std padded)
- Hysteria2 server-only fields (masquerade/ca/ca-str) in client YAML
- sing-box VMess alter_id hardcoded to 0
- sing-box missing TLS insecure + alpn mapping
- VMess per-user alterId dropped when panel creds bound
P2 Medium:
- reality-config schema missing max-time-difference + proxy (vmess/vless/trojan)
- hysteria2 realm-opts schema missing sni
Verification: go build/vet/test all PASS; gofmt clean.
fix(config): comprehensive audit vs official docs — client config + schema
Full audit against official Mihomo docs (Meta-Docs-main) found and
fixed 10 bugs across client config generation and schema completeness.
P0 Critical:
- VLESS client YAML missing network field (transport opts ignored)
- TUIC v4 token share broken (read as string, is array)
P1 High:
- SS base64 violates SIP002 (RawStd -> RawURL)
- VMess base64 inconsistency (RawStd -> Std padded)
- Hysteria2 server-only fields (masquerade/ca/ca-str) in client YAML
- sing-box VMess alter_id hardcoded to 0
- sing-box missing TLS insecure + alpn mapping
- VMess per-user alterId dropped when panel creds bound
P2 Medium:
- reality-config schema missing max-time-difference + proxy (vmess/vless/trojan)
- hysteria2 realm-opts schema missing sni
Verification: go build/vet/test all PASS; gofmt clean.
fix(config): comprehensive audit vs official docs — client config + schema
Full audit against official Mihomo docs (Meta-Docs-main) found and
fixed 10 bugs across client config generation and schema completeness.
P0 Critical:
- VLESS client YAML missing network field (transport opts ignored)
- TUIC v4 token share broken (read as string, is array)
P1 High:
- SS base64 violates SIP002 (RawStd -> RawURL)
- VMess base64 inconsistency (RawStd -> Std padded)
- Hysteria2 server-only fields (masquerade/ca/ca-str) in client YAML
- sing-box VMess alter_id hardcoded to 0
- sing-box missing TLS insecure + alpn mapping
- VMess per-user alterId dropped when panel creds bound
P2 Medium:
- reality-config schema missing max-time-difference + proxy (vmess/vless/trojan)
- hysteria2 realm-opts schema missing sni
Verification: go build/vet/test all PASS; gofmt clean.
fix(config): comprehensive audit vs official docs — client config + schema
Full audit against official Mihomo docs (Meta-Docs-main) found and
fixed 10 bugs across client config generation and schema completeness.
P0 Critical:
- VLESS client YAML missing network field (transport opts ignored)
- TUIC v4 token share broken (read as string, is array)
P1 High:
- SS base64 violates SIP002 (RawStd -> RawURL)
- VMess base64 inconsistency (RawStd -> Std padded)
- Hysteria2 server-only fields (masquerade/ca/ca-str) in client YAML
- sing-box VMess alter_id hardcoded to 0
- sing-box missing TLS insecure + alpn mapping
- VMess per-user alterId dropped when panel creds bound
P2 Medium:
- reality-config schema missing max-time-difference + proxy (vmess/vless/trojan)
- hysteria2 realm-opts schema missing sni
Verification: go build/vet/test all PASS; gofmt clean.
fix(config): comprehensive audit vs official docs — client config + schema
Full audit against official Mihomo docs (Meta-Docs-main) found and
fixed 10 bugs across client config generation and schema completeness.
P0 Critical:
- VLESS client YAML missing network field (transport opts ignored)
- TUIC v4 token share broken (read as string, is array)
P1 High:
- SS base64 violates SIP002 (RawStd -> RawURL)
- VMess base64 inconsistency (RawStd -> Std padded)
- Hysteria2 server-only fields (masquerade/ca/ca-str) in client YAML
- sing-box VMess alter_id hardcoded to 0
- sing-box missing TLS insecure + alpn mapping
- VMess per-user alterId dropped when panel creds bound
P2 Medium:
- reality-config schema missing max-time-difference + proxy (vmess/vless/trojan)
- hysteria2 realm-opts schema missing sni
Verification: go build/vet/test all PASS; gofmt clean.
fix(config): comprehensive audit vs official docs — client config + schema
Full audit against official Mihomo docs (Meta-Docs-main) found and
fixed 10 bugs across client config generation and schema completeness.
P0 Critical:
- VLESS client YAML missing network field (transport opts ignored)
- TUIC v4 token share broken (read as string, is array)
P1 High:
- SS base64 violates SIP002 (RawStd -> RawURL)
- VMess base64 inconsistency (RawStd -> Std padded)
- Hysteria2 server-only fields (masquerade/ca/ca-str) in client YAML
- sing-box VMess alter_id hardcoded to 0
- sing-box missing TLS insecure + alpn mapping
- VMess per-user alterId dropped when panel creds bound
P2 Medium:
- reality-config schema missing max-time-difference + proxy (vmess/vless/trojan)
- hysteria2 realm-opts schema missing sni
Verification: go build/vet/test all PASS; gofmt clean.
fix(config): comprehensive audit vs official docs — client config + schema
Full audit against official Mihomo docs (Meta-Docs-main) found and
fixed 10 bugs across client config generation and schema completeness.
P0 Critical:
- VLESS client YAML missing network field (transport opts ignored)
- TUIC v4 token share broken (read as string, is array)
P1 High:
- SS base64 violates SIP002 (RawStd -> RawURL)
- VMess base64 inconsistency (RawStd -> Std padded)
- Hysteria2 server-only fields (masquerade/ca/ca-str) in client YAML
- sing-box VMess alter_id hardcoded to 0
- sing-box missing TLS insecure + alpn mapping
- VMess per-user alterId dropped when panel creds bound
P2 Medium:
- reality-config schema missing max-time-difference + proxy (vmess/vless/trojan)
- hysteria2 realm-opts schema missing sni
Verification: go build/vet/test all PASS; gofmt clean.
2026-08-30 00:06:00 +00:00
風雪 126e70dbd1 fix(listeners): deep audit fixes — TUIC users, array validation, VLESS encryption, sudoku/snell autofill
Comprehensive audit of the entire listener config pipeline found and
fixed 7 bugs across autofill, validation, compilation, and schema.
== Critical (broke Mihomo) ==
C1: TUIC listener with no panel users produced empty 'users' field
autofillTUICUsers wrote users as ARRAY [{username, password}], but
the TUIC compiler (asUsersMapUUID) only reads MAP form. Compiled
output had no users → Mihomo rejected. Fixed: autofill now writes
v5 map form {'default': '<pass>'}.
C2/C3/C4: Validator rejected array-typed nested fields
anytls shadow-tls.users, anytls jls-config.users, and vmess
tlsmirror-config.embedded-traffic-generator.steps are ARRAYS of
objects in Mihomo, but the schema decomposed them into .name/
.password/.host children, making the parent require a JSON object.
Fixed: validateListenerObject now type-switches on the value —
arrays of objects are recursively validated element-by-element
against the same nested schema. Handles []interface{} and
[]map[string]interface{}.
== High (wrong config output) ==
H1: VLESS 'encryption' field silently stripped by compiler
copyConfigPassthrough had 'encryption' in its strip list (intended
to drop the client-side hint), but 'encryption' is also a legitimate
VLESS server field paired with 'decryption'. Removed it from the
strip list; panel-only keys (_-prefixed, access_profile,
transport_layer, security_layer) remain stripped.
H2: Sudoku listener created without 'key' was unusable
Sudoku uses top-level 'key' for auth (no users). Autofill had no
case for sudoku. Added: auto-generates 32-byte base64 key + defaults
aead-method to chacha20-poly1305.
H3: Snell listener created without 'version' may be rejected
Autofill set psk but never version. Added: defaults version to 4
(current Mihomo default) when unset, without clobbering pre-existing
numeric versions.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean
fix(listeners): deep audit fixes — TUIC users, array validation, VLESS encryption, sudoku/snell autofill
Comprehensive audit of the entire listener config pipeline found and
fixed 7 bugs across autofill, validation, compilation, and schema.
== Critical (broke Mihomo) ==
C1: TUIC listener with no panel users produced empty 'users' field
autofillTUICUsers wrote users as ARRAY [{username, password}], but
the TUIC compiler (asUsersMapUUID) only reads MAP form. Compiled
output had no users → Mihomo rejected. Fixed: autofill now writes
v5 map form {'default': '<pass>'}.
C2/C3/C4: Validator rejected array-typed nested fields
anytls shadow-tls.users, anytls jls-config.users, and vmess
tlsmirror-config.embedded-traffic-generator.steps are ARRAYS of
objects in Mihomo, but the schema decomposed them into .name/
.password/.host children, making the parent require a JSON object.
Fixed: validateListenerObject now type-switches on the value —
arrays of objects are recursively validated element-by-element
against the same nested schema. Handles []interface{} and
[]map[string]interface{}.
== High (wrong config output) ==
H1: VLESS 'encryption' field silently stripped by compiler
copyConfigPassthrough had 'encryption' in its strip list (intended
to drop the client-side hint), but 'encryption' is also a legitimate
VLESS server field paired with 'decryption'. Removed it from the
strip list; panel-only keys (_-prefixed, access_profile,
transport_layer, security_layer) remain stripped.
H2: Sudoku listener created without 'key' was unusable
Sudoku uses top-level 'key' for auth (no users). Autofill had no
case for sudoku. Added: auto-generates 32-byte base64 key + defaults
aead-method to chacha20-poly1305.
H3: Snell listener created without 'version' may be rejected
Autofill set psk but never version. Added: defaults version to 4
(current Mihomo default) when unset, without clobbering pre-existing
numeric versions.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean
fix(listeners): deep audit fixes — TUIC users, array validation, VLESS encryption, sudoku/snell autofill
Comprehensive audit of the entire listener config pipeline found and
fixed 7 bugs across autofill, validation, compilation, and schema.
== Critical (broke Mihomo) ==
C1: TUIC listener with no panel users produced empty 'users' field
autofillTUICUsers wrote users as ARRAY [{username, password}], but
the TUIC compiler (asUsersMapUUID) only reads MAP form. Compiled
output had no users → Mihomo rejected. Fixed: autofill now writes
v5 map form {'default': '<pass>'}.
C2/C3/C4: Validator rejected array-typed nested fields
anytls shadow-tls.users, anytls jls-config.users, and vmess
tlsmirror-config.embedded-traffic-generator.steps are ARRAYS of
objects in Mihomo, but the schema decomposed them into .name/
.password/.host children, making the parent require a JSON object.
Fixed: validateListenerObject now type-switches on the value —
arrays of objects are recursively validated element-by-element
against the same nested schema. Handles []interface{} and
[]map[string]interface{}.
== High (wrong config output) ==
H1: VLESS 'encryption' field silently stripped by compiler
copyConfigPassthrough had 'encryption' in its strip list (intended
to drop the client-side hint), but 'encryption' is also a legitimate
VLESS server field paired with 'decryption'. Removed it from the
strip list; panel-only keys (_-prefixed, access_profile,
transport_layer, security_layer) remain stripped.
H2: Sudoku listener created without 'key' was unusable
Sudoku uses top-level 'key' for auth (no users). Autofill had no
case for sudoku. Added: auto-generates 32-byte base64 key + defaults
aead-method to chacha20-poly1305.
H3: Snell listener created without 'version' may be rejected
Autofill set psk but never version. Added: defaults version to 4
(current Mihomo default) when unset, without clobbering pre-existing
numeric versions.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean
fix(listeners): deep audit fixes — TUIC users, array validation, VLESS encryption, sudoku/snell autofill
Comprehensive audit of the entire listener config pipeline found and
fixed 7 bugs across autofill, validation, compilation, and schema.
== Critical (broke Mihomo) ==
C1: TUIC listener with no panel users produced empty 'users' field
autofillTUICUsers wrote users as ARRAY [{username, password}], but
the TUIC compiler (asUsersMapUUID) only reads MAP form. Compiled
output had no users → Mihomo rejected. Fixed: autofill now writes
v5 map form {'default': '<pass>'}.
C2/C3/C4: Validator rejected array-typed nested fields
anytls shadow-tls.users, anytls jls-config.users, and vmess
tlsmirror-config.embedded-traffic-generator.steps are ARRAYS of
objects in Mihomo, but the schema decomposed them into .name/
.password/.host children, making the parent require a JSON object.
Fixed: validateListenerObject now type-switches on the value —
arrays of objects are recursively validated element-by-element
against the same nested schema. Handles []interface{} and
[]map[string]interface{}.
== High (wrong config output) ==
H1: VLESS 'encryption' field silently stripped by compiler
copyConfigPassthrough had 'encryption' in its strip list (intended
to drop the client-side hint), but 'encryption' is also a legitimate
VLESS server field paired with 'decryption'. Removed it from the
strip list; panel-only keys (_-prefixed, access_profile,
transport_layer, security_layer) remain stripped.
H2: Sudoku listener created without 'key' was unusable
Sudoku uses top-level 'key' for auth (no users). Autofill had no
case for sudoku. Added: auto-generates 32-byte base64 key + defaults
aead-method to chacha20-poly1305.
H3: Snell listener created without 'version' may be rejected
Autofill set psk but never version. Added: defaults version to 4
(current Mihomo default) when unset, without clobbering pre-existing
numeric versions.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean
fix(listeners): deep audit fixes — TUIC users, array validation, VLESS encryption, sudoku/snell autofill
Comprehensive audit of the entire listener config pipeline found and
fixed 7 bugs across autofill, validation, compilation, and schema.
== Critical (broke Mihomo) ==
C1: TUIC listener with no panel users produced empty 'users' field
autofillTUICUsers wrote users as ARRAY [{username, password}], but
the TUIC compiler (asUsersMapUUID) only reads MAP form. Compiled
output had no users → Mihomo rejected. Fixed: autofill now writes
v5 map form {'default': '<pass>'}.
C2/C3/C4: Validator rejected array-typed nested fields
anytls shadow-tls.users, anytls jls-config.users, and vmess
tlsmirror-config.embedded-traffic-generator.steps are ARRAYS of
objects in Mihomo, but the schema decomposed them into .name/
.password/.host children, making the parent require a JSON object.
Fixed: validateListenerObject now type-switches on the value —
arrays of objects are recursively validated element-by-element
against the same nested schema. Handles []interface{} and
[]map[string]interface{}.
== High (wrong config output) ==
H1: VLESS 'encryption' field silently stripped by compiler
copyConfigPassthrough had 'encryption' in its strip list (intended
to drop the client-side hint), but 'encryption' is also a legitimate
VLESS server field paired with 'decryption'. Removed it from the
strip list; panel-only keys (_-prefixed, access_profile,
transport_layer, security_layer) remain stripped.
H2: Sudoku listener created without 'key' was unusable
Sudoku uses top-level 'key' for auth (no users). Autofill had no
case for sudoku. Added: auto-generates 32-byte base64 key + defaults
aead-method to chacha20-poly1305.
H3: Snell listener created without 'version' may be rejected
Autofill set psk but never version. Added: defaults version to 4
(current Mihomo default) when unset, without clobbering pre-existing
numeric versions.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean
fix(listeners): deep audit fixes — TUIC users, array validation, VLESS encryption, sudoku/snell autofill
Comprehensive audit of the entire listener config pipeline found and
fixed 7 bugs across autofill, validation, compilation, and schema.
== Critical (broke Mihomo) ==
C1: TUIC listener with no panel users produced empty 'users' field
autofillTUICUsers wrote users as ARRAY [{username, password}], but
the TUIC compiler (asUsersMapUUID) only reads MAP form. Compiled
output had no users → Mihomo rejected. Fixed: autofill now writes
v5 map form {'default': '<pass>'}.
C2/C3/C4: Validator rejected array-typed nested fields
anytls shadow-tls.users, anytls jls-config.users, and vmess
tlsmirror-config.embedded-traffic-generator.steps are ARRAYS of
objects in Mihomo, but the schema decomposed them into .name/
.password/.host children, making the parent require a JSON object.
Fixed: validateListenerObject now type-switches on the value —
arrays of objects are recursively validated element-by-element
against the same nested schema. Handles []interface{} and
[]map[string]interface{}.
== High (wrong config output) ==
H1: VLESS 'encryption' field silently stripped by compiler
copyConfigPassthrough had 'encryption' in its strip list (intended
to drop the client-side hint), but 'encryption' is also a legitimate
VLESS server field paired with 'decryption'. Removed it from the
strip list; panel-only keys (_-prefixed, access_profile,
transport_layer, security_layer) remain stripped.
H2: Sudoku listener created without 'key' was unusable
Sudoku uses top-level 'key' for auth (no users). Autofill had no
case for sudoku. Added: auto-generates 32-byte base64 key + defaults
aead-method to chacha20-poly1305.
H3: Snell listener created without 'version' may be rejected
Autofill set psk but never version. Added: defaults version to 4
(current Mihomo default) when unset, without clobbering pre-existing
numeric versions.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean
fix(listeners): deep audit fixes — TUIC users, array validation, VLESS encryption, sudoku/snell autofill
Comprehensive audit of the entire listener config pipeline found and
fixed 7 bugs across autofill, validation, compilation, and schema.
== Critical (broke Mihomo) ==
C1: TUIC listener with no panel users produced empty 'users' field
autofillTUICUsers wrote users as ARRAY [{username, password}], but
the TUIC compiler (asUsersMapUUID) only reads MAP form. Compiled
output had no users → Mihomo rejected. Fixed: autofill now writes
v5 map form {'default': '<pass>'}.
C2/C3/C4: Validator rejected array-typed nested fields
anytls shadow-tls.users, anytls jls-config.users, and vmess
tlsmirror-config.embedded-traffic-generator.steps are ARRAYS of
objects in Mihomo, but the schema decomposed them into .name/
.password/.host children, making the parent require a JSON object.
Fixed: validateListenerObject now type-switches on the value —
arrays of objects are recursively validated element-by-element
against the same nested schema. Handles []interface{} and
[]map[string]interface{}.
== High (wrong config output) ==
H1: VLESS 'encryption' field silently stripped by compiler
copyConfigPassthrough had 'encryption' in its strip list (intended
to drop the client-side hint), but 'encryption' is also a legitimate
VLESS server field paired with 'decryption'. Removed it from the
strip list; panel-only keys (_-prefixed, access_profile,
transport_layer, security_layer) remain stripped.
H2: Sudoku listener created without 'key' was unusable
Sudoku uses top-level 'key' for auth (no users). Autofill had no
case for sudoku. Added: auto-generates 32-byte base64 key + defaults
aead-method to chacha20-poly1305.
H3: Snell listener created without 'version' may be rejected
Autofill set psk but never version. Added: defaults version to 4
(current Mihomo default) when unset, without clobbering pre-existing
numeric versions.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean
fix(listeners): deep audit fixes — TUIC users, array validation, VLESS encryption, sudoku/snell autofill
Comprehensive audit of the entire listener config pipeline found and
fixed 7 bugs across autofill, validation, compilation, and schema.
== Critical (broke Mihomo) ==
C1: TUIC listener with no panel users produced empty 'users' field
autofillTUICUsers wrote users as ARRAY [{username, password}], but
the TUIC compiler (asUsersMapUUID) only reads MAP form. Compiled
output had no users → Mihomo rejected. Fixed: autofill now writes
v5 map form {'default': '<pass>'}.
C2/C3/C4: Validator rejected array-typed nested fields
anytls shadow-tls.users, anytls jls-config.users, and vmess
tlsmirror-config.embedded-traffic-generator.steps are ARRAYS of
objects in Mihomo, but the schema decomposed them into .name/
.password/.host children, making the parent require a JSON object.
Fixed: validateListenerObject now type-switches on the value —
arrays of objects are recursively validated element-by-element
against the same nested schema. Handles []interface{} and
[]map[string]interface{}.
== High (wrong config output) ==
H1: VLESS 'encryption' field silently stripped by compiler
copyConfigPassthrough had 'encryption' in its strip list (intended
to drop the client-side hint), but 'encryption' is also a legitimate
VLESS server field paired with 'decryption'. Removed it from the
strip list; panel-only keys (_-prefixed, access_profile,
transport_layer, security_layer) remain stripped.
H2: Sudoku listener created without 'key' was unusable
Sudoku uses top-level 'key' for auth (no users). Autofill had no
case for sudoku. Added: auto-generates 32-byte base64 key + defaults
aead-method to chacha20-poly1305.
H3: Snell listener created without 'version' may be rejected
Autofill set psk but never version. Added: defaults version to 4
(current Mihomo default) when unset, without clobbering pre-existing
numeric versions.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean
fix(listeners): deep audit fixes — TUIC users, array validation, VLESS encryption, sudoku/snell autofill
Comprehensive audit of the entire listener config pipeline found and
fixed 7 bugs across autofill, validation, compilation, and schema.
== Critical (broke Mihomo) ==
C1: TUIC listener with no panel users produced empty 'users' field
autofillTUICUsers wrote users as ARRAY [{username, password}], but
the TUIC compiler (asUsersMapUUID) only reads MAP form. Compiled
output had no users → Mihomo rejected. Fixed: autofill now writes
v5 map form {'default': '<pass>'}.
C2/C3/C4: Validator rejected array-typed nested fields
anytls shadow-tls.users, anytls jls-config.users, and vmess
tlsmirror-config.embedded-traffic-generator.steps are ARRAYS of
objects in Mihomo, but the schema decomposed them into .name/
.password/.host children, making the parent require a JSON object.
Fixed: validateListenerObject now type-switches on the value —
arrays of objects are recursively validated element-by-element
against the same nested schema. Handles []interface{} and
[]map[string]interface{}.
== High (wrong config output) ==
H1: VLESS 'encryption' field silently stripped by compiler
copyConfigPassthrough had 'encryption' in its strip list (intended
to drop the client-side hint), but 'encryption' is also a legitimate
VLESS server field paired with 'decryption'. Removed it from the
strip list; panel-only keys (_-prefixed, access_profile,
transport_layer, security_layer) remain stripped.
H2: Sudoku listener created without 'key' was unusable
Sudoku uses top-level 'key' for auth (no users). Autofill had no
case for sudoku. Added: auto-generates 32-byte base64 key + defaults
aead-method to chacha20-poly1305.
H3: Snell listener created without 'version' may be rejected
Autofill set psk but never version. Added: defaults version to 4
(current Mihomo default) when unset, without clobbering pre-existing
numeric versions.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean
fix(listeners): deep audit fixes — TUIC users, array validation, VLESS encryption, sudoku/snell autofill
Comprehensive audit of the entire listener config pipeline found and
fixed 7 bugs across autofill, validation, compilation, and schema.
== Critical (broke Mihomo) ==
C1: TUIC listener with no panel users produced empty 'users' field
autofillTUICUsers wrote users as ARRAY [{username, password}], but
the TUIC compiler (asUsersMapUUID) only reads MAP form. Compiled
output had no users → Mihomo rejected. Fixed: autofill now writes
v5 map form {'default': '<pass>'}.
C2/C3/C4: Validator rejected array-typed nested fields
anytls shadow-tls.users, anytls jls-config.users, and vmess
tlsmirror-config.embedded-traffic-generator.steps are ARRAYS of
objects in Mihomo, but the schema decomposed them into .name/
.password/.host children, making the parent require a JSON object.
Fixed: validateListenerObject now type-switches on the value —
arrays of objects are recursively validated element-by-element
against the same nested schema. Handles []interface{} and
[]map[string]interface{}.
== High (wrong config output) ==
H1: VLESS 'encryption' field silently stripped by compiler
copyConfigPassthrough had 'encryption' in its strip list (intended
to drop the client-side hint), but 'encryption' is also a legitimate
VLESS server field paired with 'decryption'. Removed it from the
strip list; panel-only keys (_-prefixed, access_profile,
transport_layer, security_layer) remain stripped.
H2: Sudoku listener created without 'key' was unusable
Sudoku uses top-level 'key' for auth (no users). Autofill had no
case for sudoku. Added: auto-generates 32-byte base64 key + defaults
aead-method to chacha20-poly1305.
H3: Snell listener created without 'version' may be rejected
Autofill set psk but never version. Added: defaults version to 4
(current Mihomo default) when unset, without clobbering pre-existing
numeric versions.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean
fix(listeners): deep audit fixes — TUIC users, array validation, VLESS encryption, sudoku/snell autofill
Comprehensive audit of the entire listener config pipeline found and
fixed 7 bugs across autofill, validation, compilation, and schema.
== Critical (broke Mihomo) ==
C1: TUIC listener with no panel users produced empty 'users' field
autofillTUICUsers wrote users as ARRAY [{username, password}], but
the TUIC compiler (asUsersMapUUID) only reads MAP form. Compiled
output had no users → Mihomo rejected. Fixed: autofill now writes
v5 map form {'default': '<pass>'}.
C2/C3/C4: Validator rejected array-typed nested fields
anytls shadow-tls.users, anytls jls-config.users, and vmess
tlsmirror-config.embedded-traffic-generator.steps are ARRAYS of
objects in Mihomo, but the schema decomposed them into .name/
.password/.host children, making the parent require a JSON object.
Fixed: validateListenerObject now type-switches on the value —
arrays of objects are recursively validated element-by-element
against the same nested schema. Handles []interface{} and
[]map[string]interface{}.
== High (wrong config output) ==
H1: VLESS 'encryption' field silently stripped by compiler
copyConfigPassthrough had 'encryption' in its strip list (intended
to drop the client-side hint), but 'encryption' is also a legitimate
VLESS server field paired with 'decryption'. Removed it from the
strip list; panel-only keys (_-prefixed, access_profile,
transport_layer, security_layer) remain stripped.
H2: Sudoku listener created without 'key' was unusable
Sudoku uses top-level 'key' for auth (no users). Autofill had no
case for sudoku. Added: auto-generates 32-byte base64 key + defaults
aead-method to chacha20-poly1305.
H3: Snell listener created without 'version' may be rejected
Autofill set psk but never version. Added: defaults version to 4
(current Mihomo default) when unset, without clobbering pre-existing
numeric versions.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean
fix(listeners): deep audit fixes — TUIC users, array validation, VLESS encryption, sudoku/snell autofill
Comprehensive audit of the entire listener config pipeline found and
fixed 7 bugs across autofill, validation, compilation, and schema.
== Critical (broke Mihomo) ==
C1: TUIC listener with no panel users produced empty 'users' field
autofillTUICUsers wrote users as ARRAY [{username, password}], but
the TUIC compiler (asUsersMapUUID) only reads MAP form. Compiled
output had no users → Mihomo rejected. Fixed: autofill now writes
v5 map form {'default': '<pass>'}.
C2/C3/C4: Validator rejected array-typed nested fields
anytls shadow-tls.users, anytls jls-config.users, and vmess
tlsmirror-config.embedded-traffic-generator.steps are ARRAYS of
objects in Mihomo, but the schema decomposed them into .name/
.password/.host children, making the parent require a JSON object.
Fixed: validateListenerObject now type-switches on the value —
arrays of objects are recursively validated element-by-element
against the same nested schema. Handles []interface{} and
[]map[string]interface{}.
== High (wrong config output) ==
H1: VLESS 'encryption' field silently stripped by compiler
copyConfigPassthrough had 'encryption' in its strip list (intended
to drop the client-side hint), but 'encryption' is also a legitimate
VLESS server field paired with 'decryption'. Removed it from the
strip list; panel-only keys (_-prefixed, access_profile,
transport_layer, security_layer) remain stripped.
H2: Sudoku listener created without 'key' was unusable
Sudoku uses top-level 'key' for auth (no users). Autofill had no
case for sudoku. Added: auto-generates 32-byte base64 key + defaults
aead-method to chacha20-poly1305.
H3: Snell listener created without 'version' may be rejected
Autofill set psk but never version. Added: defaults version to 4
(current Mihomo default) when unset, without clobbering pre-existing
numeric versions.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : 15 packages all PASS
- gofmt : clean
2026-08-29 13:58:55 +00:00
風雪 9a3674685c fix(listeners): align TUIC v5 users map + TrustTunnel users injection with wiki
Continued the listener schema audit against the official Mihomo wiki
(https://wiki.metacubex.one/config/inbound/listeners/). Found and fixed
three remaining inconsistencies after the previous commit (11e8d4b).
== 1. TUIC v5 users format (was: array, should be: map) ==
Mihomo wiki TUIC v5 example:
users:
UUID1: PASSWORD1
UUID2: PASSWORD2
The TUICCompiler was using asUsersArray (producing [{username,password}]),
which is wrong for v5. Added asUsersMapUUID helper that emits
map{uuid: password} (key=UUID, falling back to Username for legacy panel
users without UUID). TUICCompiler.Compile now:
- Passes through  (TUIC v4) via copyConfigPassthrough.
- When no  is configured, emits v5 map-form users via
asUsersMapUUID.
== 2. TrustTunnel credential injection (was: missing) ==
TrustTunnel was registered as GenericCompiler{kind:"trusttunnel"}, which
does NOT inject in.Users into the compiled config — so credentials stored
in the panel DB never reached Mihomo. Created dedicated TrustTunnelCompiler
that calls asUsersArray (TrustTunnel uses users: [{username, password}]
per wiki). Updated DefaultCompileRegistry to use it.
== 3. Sudoku missing mux-option ==
Mihomo wiki sudoku example shows mux-option (commented). Added mux-option
to sudoku Fields + NestedFields in the schema registry so the validator
accepts it.
== Audit summary (all protocols vs wiki) ==
shadowsocks: cipher + password (top-level)        ✅ correct
snell:        psk + version                       ✅ correct
vmess:        users: [{username, uuid, alterId}]   ✅ correct
vless:        users: [{username, uuid, flow}]      ✅ correct (excluded per user)
trojan:       users: [{username, password}]       ✅ correct (fixed in 11e8d4b)
anytls:       users: {username: password}          ✅ correct (fixed in 11e8d4b)
mieru:        users: {username: password}          ✅ correct (fixed in 11e8d4b)
hysteria2:    users: {username: password}          ✅ correct (fixed in 11e8d4b)
tuic-v4:      token: [str]                         ✅ correct (passthrough)
tuic-v5:      users: {UUID: PASSWORD}              ✅ correct (fixed this commit)
shadowquic:   users: [{username, password}]        ✅ correct
trusttunnel:  users: [{username, password}]        ✅ correct (fixed this commit)
sudoku:       key (no password) + mux-option       ✅ correct (mux-option added this commit)
fix(listeners): align TUIC v5 users map + TrustTunnel users injection with wiki
Continued the listener schema audit against the official Mihomo wiki
(https://wiki.metacubex.one/config/inbound/listeners/). Found and fixed
three remaining inconsistencies after the previous commit (11e8d4b).
== 1. TUIC v5 users format (was: array, should be: map) ==
Mihomo wiki TUIC v5 example:
users:
UUID1: PASSWORD1
UUID2: PASSWORD2
The TUICCompiler was using asUsersArray (producing [{username,password}]),
which is wrong for v5. Added asUsersMapUUID helper that emits
map{uuid: password} (key=UUID, falling back to Username for legacy panel
users without UUID). TUICCompiler.Compile now:
- Passes through  (TUIC v4) via copyConfigPassthrough.
- When no  is configured, emits v5 map-form users via
asUsersMapUUID.
== 2. TrustTunnel credential injection (was: missing) ==
TrustTunnel was registered as GenericCompiler{kind:"trusttunnel"}, which
does NOT inject in.Users into the compiled config — so credentials stored
in the panel DB never reached Mihomo. Created dedicated TrustTunnelCompiler
that calls asUsersArray (TrustTunnel uses users: [{username, password}]
per wiki). Updated DefaultCompileRegistry to use it.
== 3. Sudoku missing mux-option ==
Mihomo wiki sudoku example shows mux-option (commented). Added mux-option
to sudoku Fields + NestedFields in the schema registry so the validator
accepts it.
== Audit summary (all protocols vs wiki) ==
shadowsocks: cipher + password (top-level)        ✅ correct
snell:        psk + version                       ✅ correct
vmess:        users: [{username, uuid, alterId}]   ✅ correct
vless:        users: [{username, uuid, flow}]      ✅ correct (excluded per user)
trojan:       users: [{username, password}]       ✅ correct (fixed in 11e8d4b)
anytls:       users: {username: password}          ✅ correct (fixed in 11e8d4b)
mieru:        users: {username: password}          ✅ correct (fixed in 11e8d4b)
hysteria2:    users: {username: password}          ✅ correct (fixed in 11e8d4b)
tuic-v4:      token: [str]                         ✅ correct (passthrough)
tuic-v5:      users: {UUID: PASSWORD}              ✅ correct (fixed this commit)
shadowquic:   users: [{username, password}]        ✅ correct
trusttunnel:  users: [{username, password}]        ✅ correct (fixed this commit)
sudoku:       key (no password) + mux-option       ✅ correct (mux-option added this commit)
fix(listeners): align TUIC v5 users map + TrustTunnel users injection with wiki
Continued the listener schema audit against the official Mihomo wiki
(https://wiki.metacubex.one/config/inbound/listeners/). Found and fixed
three remaining inconsistencies after the previous commit (11e8d4b).
== 1. TUIC v5 users format (was: array, should be: map) ==
Mihomo wiki TUIC v5 example:
users:
UUID1: PASSWORD1
UUID2: PASSWORD2
The TUICCompiler was using asUsersArray (producing [{username,password}]),
which is wrong for v5. Added asUsersMapUUID helper that emits
map{uuid: password} (key=UUID, falling back to Username for legacy panel
users without UUID). TUICCompiler.Compile now:
- Passes through  (TUIC v4) via copyConfigPassthrough.
- When no  is configured, emits v5 map-form users via
asUsersMapUUID.
== 2. TrustTunnel credential injection (was: missing) ==
TrustTunnel was registered as GenericCompiler{kind:"trusttunnel"}, which
does NOT inject in.Users into the compiled config — so credentials stored
in the panel DB never reached Mihomo. Created dedicated TrustTunnelCompiler
that calls asUsersArray (TrustTunnel uses users: [{username, password}]
per wiki). Updated DefaultCompileRegistry to use it.
== 3. Sudoku missing mux-option ==
Mihomo wiki sudoku example shows mux-option (commented). Added mux-option
to sudoku Fields + NestedFields in the schema registry so the validator
accepts it.
== Audit summary (all protocols vs wiki) ==
shadowsocks: cipher + password (top-level)        ✅ correct
snell:        psk + version                       ✅ correct
vmess:        users: [{username, uuid, alterId}]   ✅ correct
vless:        users: [{username, uuid, flow}]      ✅ correct (excluded per user)
trojan:       users: [{username, password}]       ✅ correct (fixed in 11e8d4b)
anytls:       users: {username: password}          ✅ correct (fixed in 11e8d4b)
mieru:        users: {username: password}          ✅ correct (fixed in 11e8d4b)
hysteria2:    users: {username: password}          ✅ correct (fixed in 11e8d4b)
tuic-v4:      token: [str]                         ✅ correct (passthrough)
tuic-v5:      users: {UUID: PASSWORD}              ✅ correct (fixed this commit)
shadowquic:   users: [{username, password}]        ✅ correct
trusttunnel:  users: [{username, password}]        ✅ correct (fixed this commit)
sudoku:       key (no password) + mux-option       ✅ correct (mux-option added this commit)
fix(listeners): align TUIC v5 users map + TrustTunnel users injection with wiki
Continued the listener schema audit against the official Mihomo wiki
(https://wiki.metacubex.one/config/inbound/listeners/). Found and fixed
three remaining inconsistencies after the previous commit (11e8d4b).
== 1. TUIC v5 users format (was: array, should be: map) ==
Mihomo wiki TUIC v5 example:
users:
UUID1: PASSWORD1
UUID2: PASSWORD2
The TUICCompiler was using asUsersArray (producing [{username,password}]),
which is wrong for v5. Added asUsersMapUUID helper that emits
map{uuid: password} (key=UUID, falling back to Username for legacy panel
users without UUID). TUICCompiler.Compile now:
- Passes through  (TUIC v4) via copyConfigPassthrough.
- When no  is configured, emits v5 map-form users via
asUsersMapUUID.
== 2. TrustTunnel credential injection (was: missing) ==
TrustTunnel was registered as GenericCompiler{kind:"trusttunnel"}, which
does NOT inject in.Users into the compiled config — so credentials stored
in the panel DB never reached Mihomo. Created dedicated TrustTunnelCompiler
that calls asUsersArray (TrustTunnel uses users: [{username, password}]
per wiki). Updated DefaultCompileRegistry to use it.
== 3. Sudoku missing mux-option ==
Mihomo wiki sudoku example shows mux-option (commented). Added mux-option
to sudoku Fields + NestedFields in the schema registry so the validator
accepts it.
== Audit summary (all protocols vs wiki) ==
shadowsocks: cipher + password (top-level)        ✅ correct
snell:        psk + version                       ✅ correct
vmess:        users: [{username, uuid, alterId}]   ✅ correct
vless:        users: [{username, uuid, flow}]      ✅ correct (excluded per user)
trojan:       users: [{username, password}]       ✅ correct (fixed in 11e8d4b)
anytls:       users: {username: password}          ✅ correct (fixed in 11e8d4b)
mieru:        users: {username: password}          ✅ correct (fixed in 11e8d4b)
hysteria2:    users: {username: password}          ✅ correct (fixed in 11e8d4b)
tuic-v4:      token: [str]                         ✅ correct (passthrough)
tuic-v5:      users: {UUID: PASSWORD}              ✅ correct (fixed this commit)
shadowquic:   users: [{username, password}]        ✅ correct
trusttunnel:  users: [{username, password}]        ✅ correct (fixed this commit)
sudoku:       key (no password) + mux-option       ✅ correct (mux-option added this commit)
fix(listeners): align TUIC v5 users map + TrustTunnel users injection with wiki
Continued the listener schema audit against the official Mihomo wiki
(https://wiki.metacubex.one/config/inbound/listeners/). Found and fixed
three remaining inconsistencies after the previous commit (11e8d4b).
== 1. TUIC v5 users format (was: array, should be: map) ==
Mihomo wiki TUIC v5 example:
users:
UUID1: PASSWORD1
UUID2: PASSWORD2
The TUICCompiler was using asUsersArray (producing [{username,password}]),
which is wrong for v5. Added asUsersMapUUID helper that emits
map{uuid: password} (key=UUID, falling back to Username for legacy panel
users without UUID). TUICCompiler.Compile now:
- Passes through  (TUIC v4) via copyConfigPassthrough.
- When no  is configured, emits v5 map-form users via
asUsersMapUUID.
== 2. TrustTunnel credential injection (was: missing) ==
TrustTunnel was registered as GenericCompiler{kind:"trusttunnel"}, which
does NOT inject in.Users into the compiled config — so credentials stored
in the panel DB never reached Mihomo. Created dedicated TrustTunnelCompiler
that calls asUsersArray (TrustTunnel uses users: [{username, password}]
per wiki). Updated DefaultCompileRegistry to use it.
== 3. Sudoku missing mux-option ==
Mihomo wiki sudoku example shows mux-option (commented). Added mux-option
to sudoku Fields + NestedFields in the schema registry so the validator
accepts it.
== Audit summary (all protocols vs wiki) ==
shadowsocks: cipher + password (top-level)        ✅ correct
snell:        psk + version                       ✅ correct
vmess:        users: [{username, uuid, alterId}]   ✅ correct
vless:        users: [{username, uuid, flow}]      ✅ correct (excluded per user)
trojan:       users: [{username, password}]       ✅ correct (fixed in 11e8d4b)
anytls:       users: {username: password}          ✅ correct (fixed in 11e8d4b)
mieru:        users: {username: password}          ✅ correct (fixed in 11e8d4b)
hysteria2:    users: {username: password}          ✅ correct (fixed in 11e8d4b)
tuic-v4:      token: [str]                         ✅ correct (passthrough)
tuic-v5:      users: {UUID: PASSWORD}              ✅ correct (fixed this commit)
shadowquic:   users: [{username, password}]        ✅ correct
trusttunnel:  users: [{username, password}]        ✅ correct (fixed this commit)
sudoku:       key (no password) + mux-option       ✅ correct (mux-option added this commit)
fix(listeners): align TUIC v5 users map + TrustTunnel users injection with wiki
Continued the listener schema audit against the official Mihomo wiki
(https://wiki.metacubex.one/config/inbound/listeners/). Found and fixed
three remaining inconsistencies after the previous commit (11e8d4b).
== 1. TUIC v5 users format (was: array, should be: map) ==
Mihomo wiki TUIC v5 example:
users:
UUID1: PASSWORD1
UUID2: PASSWORD2
The TUICCompiler was using asUsersArray (producing [{username,password}]),
which is wrong for v5. Added asUsersMapUUID helper that emits
map{uuid: password} (key=UUID, falling back to Username for legacy panel
users without UUID). TUICCompiler.Compile now:
- Passes through  (TUIC v4) via copyConfigPassthrough.
- When no  is configured, emits v5 map-form users via
asUsersMapUUID.
== 2. TrustTunnel credential injection (was: missing) ==
TrustTunnel was registered as GenericCompiler{kind:"trusttunnel"}, which
does NOT inject in.Users into the compiled config — so credentials stored
in the panel DB never reached Mihomo. Created dedicated TrustTunnelCompiler
that calls asUsersArray (TrustTunnel uses users: [{username, password}]
per wiki). Updated DefaultCompileRegistry to use it.
== 3. Sudoku missing mux-option ==
Mihomo wiki sudoku example shows mux-option (commented). Added mux-option
to sudoku Fields + NestedFields in the schema registry so the validator
accepts it.
== Audit summary (all protocols vs wiki) ==
shadowsocks: cipher + password (top-level)        ✅ correct
snell:        psk + version                       ✅ correct
vmess:        users: [{username, uuid, alterId}]   ✅ correct
vless:        users: [{username, uuid, flow}]      ✅ correct (excluded per user)
trojan:       users: [{username, password}]       ✅ correct (fixed in 11e8d4b)
anytls:       users: {username: password}          ✅ correct (fixed in 11e8d4b)
mieru:        users: {username: password}          ✅ correct (fixed in 11e8d4b)
hysteria2:    users: {username: password}          ✅ correct (fixed in 11e8d4b)
tuic-v4:      token: [str]                         ✅ correct (passthrough)
tuic-v5:      users: {UUID: PASSWORD}              ✅ correct (fixed this commit)
shadowquic:   users: [{username, password}]        ✅ correct
trusttunnel:  users: [{username, password}]        ✅ correct (fixed this commit)
sudoku:       key (no password) + mux-option       ✅ correct (mux-option added this commit)
fix(listeners): align TUIC v5 users map + TrustTunnel users injection with wiki
Continued the listener schema audit against the official Mihomo wiki
(https://wiki.metacubex.one/config/inbound/listeners/). Found and fixed
three remaining inconsistencies after the previous commit (11e8d4b).
== 1. TUIC v5 users format (was: array, should be: map) ==
Mihomo wiki TUIC v5 example:
users:
UUID1: PASSWORD1
UUID2: PASSWORD2
The TUICCompiler was using asUsersArray (producing [{username,password}]),
which is wrong for v5. Added asUsersMapUUID helper that emits
map{uuid: password} (key=UUID, falling back to Username for legacy panel
users without UUID). TUICCompiler.Compile now:
- Passes through  (TUIC v4) via copyConfigPassthrough.
- When no  is configured, emits v5 map-form users via
asUsersMapUUID.
== 2. TrustTunnel credential injection (was: missing) ==
TrustTunnel was registered as GenericCompiler{kind:"trusttunnel"}, which
does NOT inject in.Users into the compiled config — so credentials stored
in the panel DB never reached Mihomo. Created dedicated TrustTunnelCompiler
that calls asUsersArray (TrustTunnel uses users: [{username, password}]
per wiki). Updated DefaultCompileRegistry to use it.
== 3. Sudoku missing mux-option ==
Mihomo wiki sudoku example shows mux-option (commented). Added mux-option
to sudoku Fields + NestedFields in the schema registry so the validator
accepts it.
== Audit summary (all protocols vs wiki) ==
shadowsocks: cipher + password (top-level)        ✅ correct
snell:        psk + version                       ✅ correct
vmess:        users: [{username, uuid, alterId}]   ✅ correct
vless:        users: [{username, uuid, flow}]      ✅ correct (excluded per user)
trojan:       users: [{username, password}]       ✅ correct (fixed in 11e8d4b)
anytls:       users: {username: password}          ✅ correct (fixed in 11e8d4b)
mieru:        users: {username: password}          ✅ correct (fixed in 11e8d4b)
hysteria2:    users: {username: password}          ✅ correct (fixed in 11e8d4b)
tuic-v4:      token: [str]                         ✅ correct (passthrough)
tuic-v5:      users: {UUID: PASSWORD}              ✅ correct (fixed this commit)
shadowquic:   users: [{username, password}]        ✅ correct
trusttunnel:  users: [{username, password}]        ✅ correct (fixed this commit)
sudoku:       key (no password) + mux-option       ✅ correct (mux-option added this commit)
fix(listeners): align TUIC v5 users map + TrustTunnel users injection with wiki
Continued the listener schema audit against the official Mihomo wiki
(https://wiki.metacubex.one/config/inbound/listeners/). Found and fixed
three remaining inconsistencies after the previous commit (11e8d4b).
== 1. TUIC v5 users format (was: array, should be: map) ==
Mihomo wiki TUIC v5 example:
users:
UUID1: PASSWORD1
UUID2: PASSWORD2
The TUICCompiler was using asUsersArray (producing [{username,password}]),
which is wrong for v5. Added asUsersMapUUID helper that emits
map{uuid: password} (key=UUID, falling back to Username for legacy panel
users without UUID). TUICCompiler.Compile now:
- Passes through  (TUIC v4) via copyConfigPassthrough.
- When no  is configured, emits v5 map-form users via
asUsersMapUUID.
== 2. TrustTunnel credential injection (was: missing) ==
TrustTunnel was registered as GenericCompiler{kind:"trusttunnel"}, which
does NOT inject in.Users into the compiled config — so credentials stored
in the panel DB never reached Mihomo. Created dedicated TrustTunnelCompiler
that calls asUsersArray (TrustTunnel uses users: [{username, password}]
per wiki). Updated DefaultCompileRegistry to use it.
== 3. Sudoku missing mux-option ==
Mihomo wiki sudoku example shows mux-option (commented). Added mux-option
to sudoku Fields + NestedFields in the schema registry so the validator
accepts it.
== Audit summary (all protocols vs wiki) ==
shadowsocks: cipher + password (top-level)        ✅ correct
snell:        psk + version                       ✅ correct
vmess:        users: [{username, uuid, alterId}]   ✅ correct
vless:        users: [{username, uuid, flow}]      ✅ correct (excluded per user)
trojan:       users: [{username, password}]       ✅ correct (fixed in 11e8d4b)
anytls:       users: {username: password}          ✅ correct (fixed in 11e8d4b)
mieru:        users: {username: password}          ✅ correct (fixed in 11e8d4b)
hysteria2:    users: {username: password}          ✅ correct (fixed in 11e8d4b)
tuic-v4:      token: [str]                         ✅ correct (passthrough)
tuic-v5:      users: {UUID: PASSWORD}              ✅ correct (fixed this commit)
shadowquic:   users: [{username, password}]        ✅ correct
trusttunnel:  users: [{username, password}]        ✅ correct (fixed this commit)
sudoku:       key (no password) + mux-option       ✅ correct (mux-option added this commit)
fix(listeners): align TUIC v5 users map + TrustTunnel users injection with wiki
Continued the listener schema audit against the official Mihomo wiki
(https://wiki.metacubex.one/config/inbound/listeners/). Found and fixed
three remaining inconsistencies after the previous commit (11e8d4b).
== 1. TUIC v5 users format (was: array, should be: map) ==
Mihomo wiki TUIC v5 example:
users:
UUID1: PASSWORD1
UUID2: PASSWORD2
The TUICCompiler was using asUsersArray (producing [{username,password}]),
which is wrong for v5. Added asUsersMapUUID helper that emits
map{uuid: password} (key=UUID, falling back to Username for legacy panel
users without UUID). TUICCompiler.Compile now:
- Passes through  (TUIC v4) via copyConfigPassthrough.
- When no  is configured, emits v5 map-form users via
asUsersMapUUID.
== 2. TrustTunnel credential injection (was: missing) ==
TrustTunnel was registered as GenericCompiler{kind:"trusttunnel"}, which
does NOT inject in.Users into the compiled config — so credentials stored
in the panel DB never reached Mihomo. Created dedicated TrustTunnelCompiler
that calls asUsersArray (TrustTunnel uses users: [{username, password}]
per wiki). Updated DefaultCompileRegistry to use it.
== 3. Sudoku missing mux-option ==
Mihomo wiki sudoku example shows mux-option (commented). Added mux-option
to sudoku Fields + NestedFields in the schema registry so the validator
accepts it.
== Audit summary (all protocols vs wiki) ==
shadowsocks: cipher + password (top-level)        ✅ correct
snell:        psk + version                       ✅ correct
vmess:        users: [{username, uuid, alterId}]   ✅ correct
vless:        users: [{username, uuid, flow}]      ✅ correct (excluded per user)
trojan:       users: [{username, password}]       ✅ correct (fixed in 11e8d4b)
anytls:       users: {username: password}          ✅ correct (fixed in 11e8d4b)
mieru:        users: {username: password}          ✅ correct (fixed in 11e8d4b)
hysteria2:    users: {username: password}          ✅ correct (fixed in 11e8d4b)
tuic-v4:      token: [str]                         ✅ correct (passthrough)
tuic-v5:      users: {UUID: PASSWORD}              ✅ correct (fixed this commit)
shadowquic:   users: [{username, password}]        ✅ correct
trusttunnel:  users: [{username, password}]        ✅ correct (fixed this commit)
sudoku:       key (no password) + mux-option       ✅ correct (mux-option added this commit)
fix(listeners): align TUIC v5 users map + TrustTunnel users injection with wiki
Continued the listener schema audit against the official Mihomo wiki
(https://wiki.metacubex.one/config/inbound/listeners/). Found and fixed
three remaining inconsistencies after the previous commit (11e8d4b).
== 1. TUIC v5 users format (was: array, should be: map) ==
Mihomo wiki TUIC v5 example:
users:
UUID1: PASSWORD1
UUID2: PASSWORD2
The TUICCompiler was using asUsersArray (producing [{username,password}]),
which is wrong for v5. Added asUsersMapUUID helper that emits
map{uuid: password} (key=UUID, falling back to Username for legacy panel
users without UUID). TUICCompiler.Compile now:
- Passes through  (TUIC v4) via copyConfigPassthrough.
- When no  is configured, emits v5 map-form users via
asUsersMapUUID.
== 2. TrustTunnel credential injection (was: missing) ==
TrustTunnel was registered as GenericCompiler{kind:"trusttunnel"}, which
does NOT inject in.Users into the compiled config — so credentials stored
in the panel DB never reached Mihomo. Created dedicated TrustTunnelCompiler
that calls asUsersArray (TrustTunnel uses users: [{username, password}]
per wiki). Updated DefaultCompileRegistry to use it.
== 3. Sudoku missing mux-option ==
Mihomo wiki sudoku example shows mux-option (commented). Added mux-option
to sudoku Fields + NestedFields in the schema registry so the validator
accepts it.
== Audit summary (all protocols vs wiki) ==
shadowsocks: cipher + password (top-level)        ✅ correct
snell:        psk + version                       ✅ correct
vmess:        users: [{username, uuid, alterId}]   ✅ correct
vless:        users: [{username, uuid, flow}]      ✅ correct (excluded per user)
trojan:       users: [{username, password}]       ✅ correct (fixed in 11e8d4b)
anytls:       users: {username: password}          ✅ correct (fixed in 11e8d4b)
mieru:        users: {username: password}          ✅ correct (fixed in 11e8d4b)
hysteria2:    users: {username: password}          ✅ correct (fixed in 11e8d4b)
tuic-v4:      token: [str]                         ✅ correct (passthrough)
tuic-v5:      users: {UUID: PASSWORD}              ✅ correct (fixed this commit)
shadowquic:   users: [{username, password}]        ✅ correct
trusttunnel:  users: [{username, password}]        ✅ correct (fixed this commit)
sudoku:       key (no password) + mux-option       ✅ correct (mux-option added this commit)
fix(listeners): align TUIC v5 users map + TrustTunnel users injection with wiki
Continued the listener schema audit against the official Mihomo wiki
(https://wiki.metacubex.one/config/inbound/listeners/). Found and fixed
three remaining inconsistencies after the previous commit (11e8d4b).
== 1. TUIC v5 users format (was: array, should be: map) ==
Mihomo wiki TUIC v5 example:
users:
UUID1: PASSWORD1
UUID2: PASSWORD2
The TUICCompiler was using asUsersArray (producing [{username,password}]),
which is wrong for v5. Added asUsersMapUUID helper that emits
map{uuid: password} (key=UUID, falling back to Username for legacy panel
users without UUID). TUICCompiler.Compile now:
- Passes through  (TUIC v4) via copyConfigPassthrough.
- When no  is configured, emits v5 map-form users via
asUsersMapUUID.
== 2. TrustTunnel credential injection (was: missing) ==
TrustTunnel was registered as GenericCompiler{kind:"trusttunnel"}, which
does NOT inject in.Users into the compiled config — so credentials stored
in the panel DB never reached Mihomo. Created dedicated TrustTunnelCompiler
that calls asUsersArray (TrustTunnel uses users: [{username, password}]
per wiki). Updated DefaultCompileRegistry to use it.
== 3. Sudoku missing mux-option ==
Mihomo wiki sudoku example shows mux-option (commented). Added mux-option
to sudoku Fields + NestedFields in the schema registry so the validator
accepts it.
== Audit summary (all protocols vs wiki) ==
shadowsocks: cipher + password (top-level)        ✅ correct
snell:        psk + version                       ✅ correct
vmess:        users: [{username, uuid, alterId}]   ✅ correct
vless:        users: [{username, uuid, flow}]      ✅ correct (excluded per user)
trojan:       users: [{username, password}]       ✅ correct (fixed in 11e8d4b)
anytls:       users: {username: password}          ✅ correct (fixed in 11e8d4b)
mieru:        users: {username: password}          ✅ correct (fixed in 11e8d4b)
hysteria2:    users: {username: password}          ✅ correct (fixed in 11e8d4b)
tuic-v4:      token: [str]                         ✅ correct (passthrough)
tuic-v5:      users: {UUID: PASSWORD}              ✅ correct (fixed this commit)
shadowquic:   users: [{username, password}]        ✅ correct
trusttunnel:  users: [{username, password}]        ✅ correct (fixed this commit)
sudoku:       key (no password) + mux-option       ✅ correct (mux-option added this commit)
fix(listeners): align TUIC v5 users map + TrustTunnel users injection with wiki
Continued the listener schema audit against the official Mihomo wiki
(https://wiki.metacubex.one/config/inbound/listeners/). Found and fixed
three remaining inconsistencies after the previous commit (11e8d4b).
== 1. TUIC v5 users format (was: array, should be: map) ==
Mihomo wiki TUIC v5 example:
users:
UUID1: PASSWORD1
UUID2: PASSWORD2
The TUICCompiler was using asUsersArray (producing [{username,password}]),
which is wrong for v5. Added asUsersMapUUID helper that emits
map{uuid: password} (key=UUID, falling back to Username for legacy panel
users without UUID). TUICCompiler.Compile now:
- Passes through  (TUIC v4) via copyConfigPassthrough.
- When no  is configured, emits v5 map-form users via
asUsersMapUUID.
== 2. TrustTunnel credential injection (was: missing) ==
TrustTunnel was registered as GenericCompiler{kind:"trusttunnel"}, which
does NOT inject in.Users into the compiled config — so credentials stored
in the panel DB never reached Mihomo. Created dedicated TrustTunnelCompiler
that calls asUsersArray (TrustTunnel uses users: [{username, password}]
per wiki). Updated DefaultCompileRegistry to use it.
== 3. Sudoku missing mux-option ==
Mihomo wiki sudoku example shows mux-option (commented). Added mux-option
to sudoku Fields + NestedFields in the schema registry so the validator
accepts it.
== Audit summary (all protocols vs wiki) ==
shadowsocks: cipher + password (top-level)        ✅ correct
snell:        psk + version                       ✅ correct
vmess:        users: [{username, uuid, alterId}]   ✅ correct
vless:        users: [{username, uuid, flow}]      ✅ correct (excluded per user)
trojan:       users: [{username, password}]       ✅ correct (fixed in 11e8d4b)
anytls:       users: {username: password}          ✅ correct (fixed in 11e8d4b)
mieru:        users: {username: password}          ✅ correct (fixed in 11e8d4b)
hysteria2:    users: {username: password}          ✅ correct (fixed in 11e8d4b)
tuic-v4:      token: [str]                         ✅ correct (passthrough)
tuic-v5:      users: {UUID: PASSWORD}              ✅ correct (fixed this commit)
shadowquic:   users: [{username, password}]        ✅ correct
trusttunnel:  users: [{username, password}]        ✅ correct (fixed this commit)
sudoku:       key (no password) + mux-option       ✅ correct (mux-option added this commit)
2026-08-29 13:29:06 +00:00
風雪 90f67a6b1d fix(listeners): align auth field formats with Mihomo official listener schemas
Root cause of 'listener hy2: field password is not supported for
listener protocol hysteria2': autofillPasswordUsers created a top-level
'password' field for protocols that use 'users' (map or array) or
'token'/'key' for authentication instead.
Verified all listener protocols against https://wiki.metacubex.one/
(config/inbound/listeners/*) and fixed three classes of bugs.
== autofill.go: protocol-specific user autofill ==
Split the single autofillPasswordUsers (which created top-level
'password' for 8 protocols) into three helpers matching Mihomo schemas:
- autofillUsersMap  → hysteria2/anytls/mieru (users: {name: pass})
- autofillUsersArray → trojan/shadowquic/trusttunnel (users: [{name, pass}])
- autofillTUICUsers  → tuic (keeps existing token for v4; defaults
to v5 users array if neither token nor users set)
- Removed sudoku from the password autofill switch entirely — it
uses 'key' (top-level), not password/users.
- Deleted the old autofillPasswordUsers function.
== compile.go + compile_modules.go: users format ==
asUsersArray always returned []map (array), but hysteria2/anytls/mieru
require map{username: password}. Added asUsersMap helper. Created
dedicated AnyTLSCompiler + MieruCompiler (replacing GenericCompiler
registrations) that emit map-form users. Hysteria2Compiler.Compile
now calls asUsersMap.
Trojan/ShadowQUIC/TUIC compilers unchanged (their array format
already matches Mihomo docs: users: [{username, password}]).
== listener_schema_registry.go: missing mux-option ==
Added mux-option to hysteria2 and tuic Fields + NestedFields — both
are shown (commented) in the official Mihomo wiki examples.
== Protocol → auth format reference (verified against wiki) ==
shadowsocks: cipher + password (top-level)     ✅ unchanged
snell:        psk (top-level)                   ✅ unchanged
vmess:        users: [{username, uuid, alterId}] ✅ unchanged
vless:        users: [{username, uuid, flow}]    ✅ unchanged (excluded)
trojan:       users: [{username, password}]     ✅ fixed (was: top-level password)
anytls:       users: {username: password}        ✅ fixed (was: top-level password)
mieru:        users: {username: password}        ✅ fixed (was: top-level password)
hysteria2:    users: {username: password}        ✅ fixed (was: top-level password)
tuic-v4:      token: [str]                       ✅ fixed (was: top-level password)
tuic-v5:      users: [{username, password}]      ✅ fixed (was: top-level password)
shadowquic:   users: [{username, password}]      ✅ fixed (was: top-level password)
trusttunnel:  users: [{username, password}]      ✅ fixed (was: top-level password)
sudoku:       key (top-level, no password)       ✅ fixed (was: in password autofill)
fix(listeners): align auth field formats with Mihomo official listener schemas
Root cause of 'listener hy2: field password is not supported for
listener protocol hysteria2': autofillPasswordUsers created a top-level
'password' field for protocols that use 'users' (map or array) or
'token'/'key' for authentication instead.
Verified all listener protocols against https://wiki.metacubex.one/
(config/inbound/listeners/*) and fixed three classes of bugs.
== autofill.go: protocol-specific user autofill ==
Split the single autofillPasswordUsers (which created top-level
'password' for 8 protocols) into three helpers matching Mihomo schemas:
- autofillUsersMap  → hysteria2/anytls/mieru (users: {name: pass})
- autofillUsersArray → trojan/shadowquic/trusttunnel (users: [{name, pass}])
- autofillTUICUsers  → tuic (keeps existing token for v4; defaults
to v5 users array if neither token nor users set)
- Removed sudoku from the password autofill switch entirely — it
uses 'key' (top-level), not password/users.
- Deleted the old autofillPasswordUsers function.
== compile.go + compile_modules.go: users format ==
asUsersArray always returned []map (array), but hysteria2/anytls/mieru
require map{username: password}. Added asUsersMap helper. Created
dedicated AnyTLSCompiler + MieruCompiler (replacing GenericCompiler
registrations) that emit map-form users. Hysteria2Compiler.Compile
now calls asUsersMap.
Trojan/ShadowQUIC/TUIC compilers unchanged (their array format
already matches Mihomo docs: users: [{username, password}]).
== listener_schema_registry.go: missing mux-option ==
Added mux-option to hysteria2 and tuic Fields + NestedFields — both
are shown (commented) in the official Mihomo wiki examples.
== Protocol → auth format reference (verified against wiki) ==
shadowsocks: cipher + password (top-level)     ✅ unchanged
snell:        psk (top-level)                   ✅ unchanged
vmess:        users: [{username, uuid, alterId}] ✅ unchanged
vless:        users: [{username, uuid, flow}]    ✅ unchanged (excluded)
trojan:       users: [{username, password}]     ✅ fixed (was: top-level password)
anytls:       users: {username: password}        ✅ fixed (was: top-level password)
mieru:        users: {username: password}        ✅ fixed (was: top-level password)
hysteria2:    users: {username: password}        ✅ fixed (was: top-level password)
tuic-v4:      token: [str]                       ✅ fixed (was: top-level password)
tuic-v5:      users: [{username, password}]      ✅ fixed (was: top-level password)
shadowquic:   users: [{username, password}]      ✅ fixed (was: top-level password)
trusttunnel:  users: [{username, password}]      ✅ fixed (was: top-level password)
sudoku:       key (top-level, no password)       ✅ fixed (was: in password autofill)
fix(listeners): align auth field formats with Mihomo official listener schemas
Root cause of 'listener hy2: field password is not supported for
listener protocol hysteria2': autofillPasswordUsers created a top-level
'password' field for protocols that use 'users' (map or array) or
'token'/'key' for authentication instead.
Verified all listener protocols against https://wiki.metacubex.one/
(config/inbound/listeners/*) and fixed three classes of bugs.
== autofill.go: protocol-specific user autofill ==
Split the single autofillPasswordUsers (which created top-level
'password' for 8 protocols) into three helpers matching Mihomo schemas:
- autofillUsersMap  → hysteria2/anytls/mieru (users: {name: pass})
- autofillUsersArray → trojan/shadowquic/trusttunnel (users: [{name, pass}])
- autofillTUICUsers  → tuic (keeps existing token for v4; defaults
to v5 users array if neither token nor users set)
- Removed sudoku from the password autofill switch entirely — it
uses 'key' (top-level), not password/users.
- Deleted the old autofillPasswordUsers function.
== compile.go + compile_modules.go: users format ==
asUsersArray always returned []map (array), but hysteria2/anytls/mieru
require map{username: password}. Added asUsersMap helper. Created
dedicated AnyTLSCompiler + MieruCompiler (replacing GenericCompiler
registrations) that emit map-form users. Hysteria2Compiler.Compile
now calls asUsersMap.
Trojan/ShadowQUIC/TUIC compilers unchanged (their array format
already matches Mihomo docs: users: [{username, password}]).
== listener_schema_registry.go: missing mux-option ==
Added mux-option to hysteria2 and tuic Fields + NestedFields — both
are shown (commented) in the official Mihomo wiki examples.
== Protocol → auth format reference (verified against wiki) ==
shadowsocks: cipher + password (top-level)     ✅ unchanged
snell:        psk (top-level)                   ✅ unchanged
vmess:        users: [{username, uuid, alterId}] ✅ unchanged
vless:        users: [{username, uuid, flow}]    ✅ unchanged (excluded)
trojan:       users: [{username, password}]     ✅ fixed (was: top-level password)
anytls:       users: {username: password}        ✅ fixed (was: top-level password)
mieru:        users: {username: password}        ✅ fixed (was: top-level password)
hysteria2:    users: {username: password}        ✅ fixed (was: top-level password)
tuic-v4:      token: [str]                       ✅ fixed (was: top-level password)
tuic-v5:      users: [{username, password}]      ✅ fixed (was: top-level password)
shadowquic:   users: [{username, password}]      ✅ fixed (was: top-level password)
trusttunnel:  users: [{username, password}]      ✅ fixed (was: top-level password)
sudoku:       key (top-level, no password)       ✅ fixed (was: in password autofill)
fix(listeners): align auth field formats with Mihomo official listener schemas
Root cause of 'listener hy2: field password is not supported for
listener protocol hysteria2': autofillPasswordUsers created a top-level
'password' field for protocols that use 'users' (map or array) or
'token'/'key' for authentication instead.
Verified all listener protocols against https://wiki.metacubex.one/
(config/inbound/listeners/*) and fixed three classes of bugs.
== autofill.go: protocol-specific user autofill ==
Split the single autofillPasswordUsers (which created top-level
'password' for 8 protocols) into three helpers matching Mihomo schemas:
- autofillUsersMap  → hysteria2/anytls/mieru (users: {name: pass})
- autofillUsersArray → trojan/shadowquic/trusttunnel (users: [{name, pass}])
- autofillTUICUsers  → tuic (keeps existing token for v4; defaults
to v5 users array if neither token nor users set)
- Removed sudoku from the password autofill switch entirely — it
uses 'key' (top-level), not password/users.
- Deleted the old autofillPasswordUsers function.
== compile.go + compile_modules.go: users format ==
asUsersArray always returned []map (array), but hysteria2/anytls/mieru
require map{username: password}. Added asUsersMap helper. Created
dedicated AnyTLSCompiler + MieruCompiler (replacing GenericCompiler
registrations) that emit map-form users. Hysteria2Compiler.Compile
now calls asUsersMap.
Trojan/ShadowQUIC/TUIC compilers unchanged (their array format
already matches Mihomo docs: users: [{username, password}]).
== listener_schema_registry.go: missing mux-option ==
Added mux-option to hysteria2 and tuic Fields + NestedFields — both
are shown (commented) in the official Mihomo wiki examples.
== Protocol → auth format reference (verified against wiki) ==
shadowsocks: cipher + password (top-level)     ✅ unchanged
snell:        psk (top-level)                   ✅ unchanged
vmess:        users: [{username, uuid, alterId}] ✅ unchanged
vless:        users: [{username, uuid, flow}]    ✅ unchanged (excluded)
trojan:       users: [{username, password}]     ✅ fixed (was: top-level password)
anytls:       users: {username: password}        ✅ fixed (was: top-level password)
mieru:        users: {username: password}        ✅ fixed (was: top-level password)
hysteria2:    users: {username: password}        ✅ fixed (was: top-level password)
tuic-v4:      token: [str]                       ✅ fixed (was: top-level password)
tuic-v5:      users: [{username, password}]      ✅ fixed (was: top-level password)
shadowquic:   users: [{username, password}]      ✅ fixed (was: top-level password)
trusttunnel:  users: [{username, password}]      ✅ fixed (was: top-level password)
sudoku:       key (top-level, no password)       ✅ fixed (was: in password autofill)
fix(listeners): align auth field formats with Mihomo official listener schemas
Root cause of 'listener hy2: field password is not supported for
listener protocol hysteria2': autofillPasswordUsers created a top-level
'password' field for protocols that use 'users' (map or array) or
'token'/'key' for authentication instead.
Verified all listener protocols against https://wiki.metacubex.one/
(config/inbound/listeners/*) and fixed three classes of bugs.
== autofill.go: protocol-specific user autofill ==
Split the single autofillPasswordUsers (which created top-level
'password' for 8 protocols) into three helpers matching Mihomo schemas:
- autofillUsersMap  → hysteria2/anytls/mieru (users: {name: pass})
- autofillUsersArray → trojan/shadowquic/trusttunnel (users: [{name, pass}])
- autofillTUICUsers  → tuic (keeps existing token for v4; defaults
to v5 users array if neither token nor users set)
- Removed sudoku from the password autofill switch entirely — it
uses 'key' (top-level), not password/users.
- Deleted the old autofillPasswordUsers function.
== compile.go + compile_modules.go: users format ==
asUsersArray always returned []map (array), but hysteria2/anytls/mieru
require map{username: password}. Added asUsersMap helper. Created
dedicated AnyTLSCompiler + MieruCompiler (replacing GenericCompiler
registrations) that emit map-form users. Hysteria2Compiler.Compile
now calls asUsersMap.
Trojan/ShadowQUIC/TUIC compilers unchanged (their array format
already matches Mihomo docs: users: [{username, password}]).
== listener_schema_registry.go: missing mux-option ==
Added mux-option to hysteria2 and tuic Fields + NestedFields — both
are shown (commented) in the official Mihomo wiki examples.
== Protocol → auth format reference (verified against wiki) ==
shadowsocks: cipher + password (top-level)     ✅ unchanged
snell:        psk (top-level)                   ✅ unchanged
vmess:        users: [{username, uuid, alterId}] ✅ unchanged
vless:        users: [{username, uuid, flow}]    ✅ unchanged (excluded)
trojan:       users: [{username, password}]     ✅ fixed (was: top-level password)
anytls:       users: {username: password}        ✅ fixed (was: top-level password)
mieru:        users: {username: password}        ✅ fixed (was: top-level password)
hysteria2:    users: {username: password}        ✅ fixed (was: top-level password)
tuic-v4:      token: [str]                       ✅ fixed (was: top-level password)
tuic-v5:      users: [{username, password}]      ✅ fixed (was: top-level password)
shadowquic:   users: [{username, password}]      ✅ fixed (was: top-level password)
trusttunnel:  users: [{username, password}]      ✅ fixed (was: top-level password)
sudoku:       key (top-level, no password)       ✅ fixed (was: in password autofill)
fix(listeners): align auth field formats with Mihomo official listener schemas
Root cause of 'listener hy2: field password is not supported for
listener protocol hysteria2': autofillPasswordUsers created a top-level
'password' field for protocols that use 'users' (map or array) or
'token'/'key' for authentication instead.
Verified all listener protocols against https://wiki.metacubex.one/
(config/inbound/listeners/*) and fixed three classes of bugs.
== autofill.go: protocol-specific user autofill ==
Split the single autofillPasswordUsers (which created top-level
'password' for 8 protocols) into three helpers matching Mihomo schemas:
- autofillUsersMap  → hysteria2/anytls/mieru (users: {name: pass})
- autofillUsersArray → trojan/shadowquic/trusttunnel (users: [{name, pass}])
- autofillTUICUsers  → tuic (keeps existing token for v4; defaults
to v5 users array if neither token nor users set)
- Removed sudoku from the password autofill switch entirely — it
uses 'key' (top-level), not password/users.
- Deleted the old autofillPasswordUsers function.
== compile.go + compile_modules.go: users format ==
asUsersArray always returned []map (array), but hysteria2/anytls/mieru
require map{username: password}. Added asUsersMap helper. Created
dedicated AnyTLSCompiler + MieruCompiler (replacing GenericCompiler
registrations) that emit map-form users. Hysteria2Compiler.Compile
now calls asUsersMap.
Trojan/ShadowQUIC/TUIC compilers unchanged (their array format
already matches Mihomo docs: users: [{username, password}]).
== listener_schema_registry.go: missing mux-option ==
Added mux-option to hysteria2 and tuic Fields + NestedFields — both
are shown (commented) in the official Mihomo wiki examples.
== Protocol → auth format reference (verified against wiki) ==
shadowsocks: cipher + password (top-level)     ✅ unchanged
snell:        psk (top-level)                   ✅ unchanged
vmess:        users: [{username, uuid, alterId}] ✅ unchanged
vless:        users: [{username, uuid, flow}]    ✅ unchanged (excluded)
trojan:       users: [{username, password}]     ✅ fixed (was: top-level password)
anytls:       users: {username: password}        ✅ fixed (was: top-level password)
mieru:        users: {username: password}        ✅ fixed (was: top-level password)
hysteria2:    users: {username: password}        ✅ fixed (was: top-level password)
tuic-v4:      token: [str]                       ✅ fixed (was: top-level password)
tuic-v5:      users: [{username, password}]      ✅ fixed (was: top-level password)
shadowquic:   users: [{username, password}]      ✅ fixed (was: top-level password)
trusttunnel:  users: [{username, password}]      ✅ fixed (was: top-level password)
sudoku:       key (top-level, no password)       ✅ fixed (was: in password autofill)
fix(listeners): align auth field formats with Mihomo official listener schemas
Root cause of 'listener hy2: field password is not supported for
listener protocol hysteria2': autofillPasswordUsers created a top-level
'password' field for protocols that use 'users' (map or array) or
'token'/'key' for authentication instead.
Verified all listener protocols against https://wiki.metacubex.one/
(config/inbound/listeners/*) and fixed three classes of bugs.
== autofill.go: protocol-specific user autofill ==
Split the single autofillPasswordUsers (which created top-level
'password' for 8 protocols) into three helpers matching Mihomo schemas:
- autofillUsersMap  → hysteria2/anytls/mieru (users: {name: pass})
- autofillUsersArray → trojan/shadowquic/trusttunnel (users: [{name, pass}])
- autofillTUICUsers  → tuic (keeps existing token for v4; defaults
to v5 users array if neither token nor users set)
- Removed sudoku from the password autofill switch entirely — it
uses 'key' (top-level), not password/users.
- Deleted the old autofillPasswordUsers function.
== compile.go + compile_modules.go: users format ==
asUsersArray always returned []map (array), but hysteria2/anytls/mieru
require map{username: password}. Added asUsersMap helper. Created
dedicated AnyTLSCompiler + MieruCompiler (replacing GenericCompiler
registrations) that emit map-form users. Hysteria2Compiler.Compile
now calls asUsersMap.
Trojan/ShadowQUIC/TUIC compilers unchanged (their array format
already matches Mihomo docs: users: [{username, password}]).
== listener_schema_registry.go: missing mux-option ==
Added mux-option to hysteria2 and tuic Fields + NestedFields — both
are shown (commented) in the official Mihomo wiki examples.
== Protocol → auth format reference (verified against wiki) ==
shadowsocks: cipher + password (top-level)     ✅ unchanged
snell:        psk (top-level)                   ✅ unchanged
vmess:        users: [{username, uuid, alterId}] ✅ unchanged
vless:        users: [{username, uuid, flow}]    ✅ unchanged (excluded)
trojan:       users: [{username, password}]     ✅ fixed (was: top-level password)
anytls:       users: {username: password}        ✅ fixed (was: top-level password)
mieru:        users: {username: password}        ✅ fixed (was: top-level password)
hysteria2:    users: {username: password}        ✅ fixed (was: top-level password)
tuic-v4:      token: [str]                       ✅ fixed (was: top-level password)
tuic-v5:      users: [{username, password}]      ✅ fixed (was: top-level password)
shadowquic:   users: [{username, password}]      ✅ fixed (was: top-level password)
trusttunnel:  users: [{username, password}]      ✅ fixed (was: top-level password)
sudoku:       key (top-level, no password)       ✅ fixed (was: in password autofill)
fix(listeners): align auth field formats with Mihomo official listener schemas
Root cause of 'listener hy2: field password is not supported for
listener protocol hysteria2': autofillPasswordUsers created a top-level
'password' field for protocols that use 'users' (map or array) or
'token'/'key' for authentication instead.
Verified all listener protocols against https://wiki.metacubex.one/
(config/inbound/listeners/*) and fixed three classes of bugs.
== autofill.go: protocol-specific user autofill ==
Split the single autofillPasswordUsers (which created top-level
'password' for 8 protocols) into three helpers matching Mihomo schemas:
- autofillUsersMap  → hysteria2/anytls/mieru (users: {name: pass})
- autofillUsersArray → trojan/shadowquic/trusttunnel (users: [{name, pass}])
- autofillTUICUsers  → tuic (keeps existing token for v4; defaults
to v5 users array if neither token nor users set)
- Removed sudoku from the password autofill switch entirely — it
uses 'key' (top-level), not password/users.
- Deleted the old autofillPasswordUsers function.
== compile.go + compile_modules.go: users format ==
asUsersArray always returned []map (array), but hysteria2/anytls/mieru
require map{username: password}. Added asUsersMap helper. Created
dedicated AnyTLSCompiler + MieruCompiler (replacing GenericCompiler
registrations) that emit map-form users. Hysteria2Compiler.Compile
now calls asUsersMap.
Trojan/ShadowQUIC/TUIC compilers unchanged (their array format
already matches Mihomo docs: users: [{username, password}]).
== listener_schema_registry.go: missing mux-option ==
Added mux-option to hysteria2 and tuic Fields + NestedFields — both
are shown (commented) in the official Mihomo wiki examples.
== Protocol → auth format reference (verified against wiki) ==
shadowsocks: cipher + password (top-level)     ✅ unchanged
snell:        psk (top-level)                   ✅ unchanged
vmess:        users: [{username, uuid, alterId}] ✅ unchanged
vless:        users: [{username, uuid, flow}]    ✅ unchanged (excluded)
trojan:       users: [{username, password}]     ✅ fixed (was: top-level password)
anytls:       users: {username: password}        ✅ fixed (was: top-level password)
mieru:        users: {username: password}        ✅ fixed (was: top-level password)
hysteria2:    users: {username: password}        ✅ fixed (was: top-level password)
tuic-v4:      token: [str]                       ✅ fixed (was: top-level password)
tuic-v5:      users: [{username, password}]      ✅ fixed (was: top-level password)
shadowquic:   users: [{username, password}]      ✅ fixed (was: top-level password)
trusttunnel:  users: [{username, password}]      ✅ fixed (was: top-level password)
sudoku:       key (top-level, no password)       ✅ fixed (was: in password autofill)
fix(listeners): align auth field formats with Mihomo official listener schemas
Root cause of 'listener hy2: field password is not supported for
listener protocol hysteria2': autofillPasswordUsers created a top-level
'password' field for protocols that use 'users' (map or array) or
'token'/'key' for authentication instead.
Verified all listener protocols against https://wiki.metacubex.one/
(config/inbound/listeners/*) and fixed three classes of bugs.
== autofill.go: protocol-specific user autofill ==
Split the single autofillPasswordUsers (which created top-level
'password' for 8 protocols) into three helpers matching Mihomo schemas:
- autofillUsersMap  → hysteria2/anytls/mieru (users: {name: pass})
- autofillUsersArray → trojan/shadowquic/trusttunnel (users: [{name, pass}])
- autofillTUICUsers  → tuic (keeps existing token for v4; defaults
to v5 users array if neither token nor users set)
- Removed sudoku from the password autofill switch entirely — it
uses 'key' (top-level), not password/users.
- Deleted the old autofillPasswordUsers function.
== compile.go + compile_modules.go: users format ==
asUsersArray always returned []map (array), but hysteria2/anytls/mieru
require map{username: password}. Added asUsersMap helper. Created
dedicated AnyTLSCompiler + MieruCompiler (replacing GenericCompiler
registrations) that emit map-form users. Hysteria2Compiler.Compile
now calls asUsersMap.
Trojan/ShadowQUIC/TUIC compilers unchanged (their array format
already matches Mihomo docs: users: [{username, password}]).
== listener_schema_registry.go: missing mux-option ==
Added mux-option to hysteria2 and tuic Fields + NestedFields — both
are shown (commented) in the official Mihomo wiki examples.
== Protocol → auth format reference (verified against wiki) ==
shadowsocks: cipher + password (top-level)     ✅ unchanged
snell:        psk (top-level)                   ✅ unchanged
vmess:        users: [{username, uuid, alterId}] ✅ unchanged
vless:        users: [{username, uuid, flow}]    ✅ unchanged (excluded)
trojan:       users: [{username, password}]     ✅ fixed (was: top-level password)
anytls:       users: {username: password}        ✅ fixed (was: top-level password)
mieru:        users: {username: password}        ✅ fixed (was: top-level password)
hysteria2:    users: {username: password}        ✅ fixed (was: top-level password)
tuic-v4:      token: [str]                       ✅ fixed (was: top-level password)
tuic-v5:      users: [{username, password}]      ✅ fixed (was: top-level password)
shadowquic:   users: [{username, password}]      ✅ fixed (was: top-level password)
trusttunnel:  users: [{username, password}]      ✅ fixed (was: top-level password)
sudoku:       key (top-level, no password)       ✅ fixed (was: in password autofill)
fix(listeners): align auth field formats with Mihomo official listener schemas
Root cause of 'listener hy2: field password is not supported for
listener protocol hysteria2': autofillPasswordUsers created a top-level
'password' field for protocols that use 'users' (map or array) or
'token'/'key' for authentication instead.
Verified all listener protocols against https://wiki.metacubex.one/
(config/inbound/listeners/*) and fixed three classes of bugs.
== autofill.go: protocol-specific user autofill ==
Split the single autofillPasswordUsers (which created top-level
'password' for 8 protocols) into three helpers matching Mihomo schemas:
- autofillUsersMap  → hysteria2/anytls/mieru (users: {name: pass})
- autofillUsersArray → trojan/shadowquic/trusttunnel (users: [{name, pass}])
- autofillTUICUsers  → tuic (keeps existing token for v4; defaults
to v5 users array if neither token nor users set)
- Removed sudoku from the password autofill switch entirely — it
uses 'key' (top-level), not password/users.
- Deleted the old autofillPasswordUsers function.
== compile.go + compile_modules.go: users format ==
asUsersArray always returned []map (array), but hysteria2/anytls/mieru
require map{username: password}. Added asUsersMap helper. Created
dedicated AnyTLSCompiler + MieruCompiler (replacing GenericCompiler
registrations) that emit map-form users. Hysteria2Compiler.Compile
now calls asUsersMap.
Trojan/ShadowQUIC/TUIC compilers unchanged (their array format
already matches Mihomo docs: users: [{username, password}]).
== listener_schema_registry.go: missing mux-option ==
Added mux-option to hysteria2 and tuic Fields + NestedFields — both
are shown (commented) in the official Mihomo wiki examples.
== Protocol → auth format reference (verified against wiki) ==
shadowsocks: cipher + password (top-level)     ✅ unchanged
snell:        psk (top-level)                   ✅ unchanged
vmess:        users: [{username, uuid, alterId}] ✅ unchanged
vless:        users: [{username, uuid, flow}]    ✅ unchanged (excluded)
trojan:       users: [{username, password}]     ✅ fixed (was: top-level password)
anytls:       users: {username: password}        ✅ fixed (was: top-level password)
mieru:        users: {username: password}        ✅ fixed (was: top-level password)
hysteria2:    users: {username: password}        ✅ fixed (was: top-level password)
tuic-v4:      token: [str]                       ✅ fixed (was: top-level password)
tuic-v5:      users: [{username, password}]      ✅ fixed (was: top-level password)
shadowquic:   users: [{username, password}]      ✅ fixed (was: top-level password)
trusttunnel:  users: [{username, password}]      ✅ fixed (was: top-level password)
sudoku:       key (top-level, no password)       ✅ fixed (was: in password autofill)
fix(listeners): align auth field formats with Mihomo official listener schemas
Root cause of 'listener hy2: field password is not supported for
listener protocol hysteria2': autofillPasswordUsers created a top-level
'password' field for protocols that use 'users' (map or array) or
'token'/'key' for authentication instead.
Verified all listener protocols against https://wiki.metacubex.one/
(config/inbound/listeners/*) and fixed three classes of bugs.
== autofill.go: protocol-specific user autofill ==
Split the single autofillPasswordUsers (which created top-level
'password' for 8 protocols) into three helpers matching Mihomo schemas:
- autofillUsersMap  → hysteria2/anytls/mieru (users: {name: pass})
- autofillUsersArray → trojan/shadowquic/trusttunnel (users: [{name, pass}])
- autofillTUICUsers  → tuic (keeps existing token for v4; defaults
to v5 users array if neither token nor users set)
- Removed sudoku from the password autofill switch entirely — it
uses 'key' (top-level), not password/users.
- Deleted the old autofillPasswordUsers function.
== compile.go + compile_modules.go: users format ==
asUsersArray always returned []map (array), but hysteria2/anytls/mieru
require map{username: password}. Added asUsersMap helper. Created
dedicated AnyTLSCompiler + MieruCompiler (replacing GenericCompiler
registrations) that emit map-form users. Hysteria2Compiler.Compile
now calls asUsersMap.
Trojan/ShadowQUIC/TUIC compilers unchanged (their array format
already matches Mihomo docs: users: [{username, password}]).
== listener_schema_registry.go: missing mux-option ==
Added mux-option to hysteria2 and tuic Fields + NestedFields — both
are shown (commented) in the official Mihomo wiki examples.
== Protocol → auth format reference (verified against wiki) ==
shadowsocks: cipher + password (top-level)     ✅ unchanged
snell:        psk (top-level)                   ✅ unchanged
vmess:        users: [{username, uuid, alterId}] ✅ unchanged
vless:        users: [{username, uuid, flow}]    ✅ unchanged (excluded)
trojan:       users: [{username, password}]     ✅ fixed (was: top-level password)
anytls:       users: {username: password}        ✅ fixed (was: top-level password)
mieru:        users: {username: password}        ✅ fixed (was: top-level password)
hysteria2:    users: {username: password}        ✅ fixed (was: top-level password)
tuic-v4:      token: [str]                       ✅ fixed (was: top-level password)
tuic-v5:      users: [{username, password}]      ✅ fixed (was: top-level password)
shadowquic:   users: [{username, password}]      ✅ fixed (was: top-level password)
trusttunnel:  users: [{username, password}]      ✅ fixed (was: top-level password)
sudoku:       key (top-level, no password)       ✅ fixed (was: in password autofill)
fix(listeners): align auth field formats with Mihomo official listener schemas
Root cause of 'listener hy2: field password is not supported for
listener protocol hysteria2': autofillPasswordUsers created a top-level
'password' field for protocols that use 'users' (map or array) or
'token'/'key' for authentication instead.
Verified all listener protocols against https://wiki.metacubex.one/
(config/inbound/listeners/*) and fixed three classes of bugs.
== autofill.go: protocol-specific user autofill ==
Split the single autofillPasswordUsers (which created top-level
'password' for 8 protocols) into three helpers matching Mihomo schemas:
- autofillUsersMap  → hysteria2/anytls/mieru (users: {name: pass})
- autofillUsersArray → trojan/shadowquic/trusttunnel (users: [{name, pass}])
- autofillTUICUsers  → tuic (keeps existing token for v4; defaults
to v5 users array if neither token nor users set)
- Removed sudoku from the password autofill switch entirely — it
uses 'key' (top-level), not password/users.
- Deleted the old autofillPasswordUsers function.
== compile.go + compile_modules.go: users format ==
asUsersArray always returned []map (array), but hysteria2/anytls/mieru
require map{username: password}. Added asUsersMap helper. Created
dedicated AnyTLSCompiler + MieruCompiler (replacing GenericCompiler
registrations) that emit map-form users. Hysteria2Compiler.Compile
now calls asUsersMap.
Trojan/ShadowQUIC/TUIC compilers unchanged (their array format
already matches Mihomo docs: users: [{username, password}]).
== listener_schema_registry.go: missing mux-option ==
Added mux-option to hysteria2 and tuic Fields + NestedFields — both
are shown (commented) in the official Mihomo wiki examples.
== Protocol → auth format reference (verified against wiki) ==
shadowsocks: cipher + password (top-level)     ✅ unchanged
snell:        psk (top-level)                   ✅ unchanged
vmess:        users: [{username, uuid, alterId}] ✅ unchanged
vless:        users: [{username, uuid, flow}]    ✅ unchanged (excluded)
trojan:       users: [{username, password}]     ✅ fixed (was: top-level password)
anytls:       users: {username: password}        ✅ fixed (was: top-level password)
mieru:        users: {username: password}        ✅ fixed (was: top-level password)
hysteria2:    users: {username: password}        ✅ fixed (was: top-level password)
tuic-v4:      token: [str]                       ✅ fixed (was: top-level password)
tuic-v5:      users: [{username, password}]      ✅ fixed (was: top-level password)
shadowquic:   users: [{username, password}]      ✅ fixed (was: top-level password)
trusttunnel:  users: [{username, password}]      ✅ fixed (was: top-level password)
sudoku:       key (top-level, no password)       ✅ fixed (was: in password autofill)
2026-08-29 12:54:25 +00:00
風雪 0f234c0efe fix(protocol): restore broken share_modules.go and implement VLESS BuildShare
The previous commit 658ef5c left share_modules.go starting with 'if'
instead of 'package protocol', making the whole module unbuildable.
This restores:
- package declaration and imports
- Trojan / Shadowsocks / Hysteria2 BuildShare methods
- the missing VLESSCompiler.BuildShare (expected by share_reality_test.go)
Also fixes reality public-key encoding in node/uri_builders.go to use
RawURLEncoding (URL-safe) consistently, matching protocol expectations.
Fixes: 658ef5c (build was broken)
fix(protocol): restore broken share_modules.go and implement VLESS BuildShare
The previous commit 658ef5c left share_modules.go starting with 'if'
instead of 'package protocol', making the whole module unbuildable.
This restores:
- package declaration and imports
- Trojan / Shadowsocks / Hysteria2 BuildShare methods
- the missing VLESSCompiler.BuildShare (expected by share_reality_test.go)
Also fixes reality public-key encoding in node/uri_builders.go to use
RawURLEncoding (URL-safe) consistently, matching protocol expectations.
Fixes: 658ef5c (build was broken)
fix(protocol): restore broken share_modules.go and implement VLESS BuildShare
The previous commit 658ef5c left share_modules.go starting with 'if'
instead of 'package protocol', making the whole module unbuildable.
This restores:
- package declaration and imports
- Trojan / Shadowsocks / Hysteria2 BuildShare methods
- the missing VLESSCompiler.BuildShare (expected by share_reality_test.go)
Also fixes reality public-key encoding in node/uri_builders.go to use
RawURLEncoding (URL-safe) consistently, matching protocol expectations.
Fixes: 658ef5c (build was broken)
fix(protocol): restore broken share_modules.go and implement VLESS BuildShare
The previous commit 658ef5c left share_modules.go starting with 'if'
instead of 'package protocol', making the whole module unbuildable.
This restores:
- package declaration and imports
- Trojan / Shadowsocks / Hysteria2 BuildShare methods
- the missing VLESSCompiler.BuildShare (expected by share_reality_test.go)
Also fixes reality public-key encoding in node/uri_builders.go to use
RawURLEncoding (URL-safe) consistently, matching protocol expectations.
Fixes: 658ef5c (build was broken)
fix(protocol): restore broken share_modules.go and implement VLESS BuildShare
The previous commit 658ef5c left share_modules.go starting with 'if'
instead of 'package protocol', making the whole module unbuildable.
This restores:
- package declaration and imports
- Trojan / Shadowsocks / Hysteria2 BuildShare methods
- the missing VLESSCompiler.BuildShare (expected by share_reality_test.go)
Also fixes reality public-key encoding in node/uri_builders.go to use
RawURLEncoding (URL-safe) consistently, matching protocol expectations.
Fixes: 658ef5c (build was broken)
fix(protocol): restore broken share_modules.go and implement VLESS BuildShare
The previous commit 658ef5c left share_modules.go starting with 'if'
instead of 'package protocol', making the whole module unbuildable.
This restores:
- package declaration and imports
- Trojan / Shadowsocks / Hysteria2 BuildShare methods
- the missing VLESSCompiler.BuildShare (expected by share_reality_test.go)
Also fixes reality public-key encoding in node/uri_builders.go to use
RawURLEncoding (URL-safe) consistently, matching protocol expectations.
Fixes: 658ef5c (build was broken)
fix(protocol): restore broken share_modules.go and implement VLESS BuildShare
The previous commit 658ef5c left share_modules.go starting with 'if'
instead of 'package protocol', making the whole module unbuildable.
This restores:
- package declaration and imports
- Trojan / Shadowsocks / Hysteria2 BuildShare methods
- the missing VLESSCompiler.BuildShare (expected by share_reality_test.go)
Also fixes reality public-key encoding in node/uri_builders.go to use
RawURLEncoding (URL-safe) consistently, matching protocol expectations.
Fixes: 658ef5c (build was broken)
fix(protocol): restore broken share_modules.go and implement VLESS BuildShare
The previous commit 658ef5c left share_modules.go starting with 'if'
instead of 'package protocol', making the whole module unbuildable.
This restores:
- package declaration and imports
- Trojan / Shadowsocks / Hysteria2 BuildShare methods
- the missing VLESSCompiler.BuildShare (expected by share_reality_test.go)
Also fixes reality public-key encoding in node/uri_builders.go to use
RawURLEncoding (URL-safe) consistently, matching protocol expectations.
Fixes: 658ef5c (build was broken)
fix(protocol): restore broken share_modules.go and implement VLESS BuildShare
The previous commit 658ef5c left share_modules.go starting with 'if'
instead of 'package protocol', making the whole module unbuildable.
This restores:
- package declaration and imports
- Trojan / Shadowsocks / Hysteria2 BuildShare methods
- the missing VLESSCompiler.BuildShare (expected by share_reality_test.go)
Also fixes reality public-key encoding in node/uri_builders.go to use
RawURLEncoding (URL-safe) consistently, matching protocol expectations.
Fixes: 658ef5c (build was broken)
fix(protocol): restore broken share_modules.go and implement VLESS BuildShare
The previous commit 658ef5c left share_modules.go starting with 'if'
instead of 'package protocol', making the whole module unbuildable.
This restores:
- package declaration and imports
- Trojan / Shadowsocks / Hysteria2 BuildShare methods
- the missing VLESSCompiler.BuildShare (expected by share_reality_test.go)
Also fixes reality public-key encoding in node/uri_builders.go to use
RawURLEncoding (URL-safe) consistently, matching protocol expectations.
Fixes: 658ef5c (build was broken)
fix(protocol): restore broken share_modules.go and implement VLESS BuildShare
The previous commit 658ef5c left share_modules.go starting with 'if'
instead of 'package protocol', making the whole module unbuildable.
This restores:
- package declaration and imports
- Trojan / Shadowsocks / Hysteria2 BuildShare methods
- the missing VLESSCompiler.BuildShare (expected by share_reality_test.go)
Also fixes reality public-key encoding in node/uri_builders.go to use
RawURLEncoding (URL-safe) consistently, matching protocol expectations.
Fixes: 658ef5c (build was broken)
fix(protocol): restore broken share_modules.go and implement VLESS BuildShare
The previous commit 658ef5c left share_modules.go starting with 'if'
instead of 'package protocol', making the whole module unbuildable.
This restores:
- package declaration and imports
- Trojan / Shadowsocks / Hysteria2 BuildShare methods
- the missing VLESSCompiler.BuildShare (expected by share_reality_test.go)
Also fixes reality public-key encoding in node/uri_builders.go to use
RawURLEncoding (URL-safe) consistently, matching protocol expectations.
Fixes: 658ef5c (build was broken)
2026-08-29 09:38:25 +00:00
風雪 6bf5941d41 restore protocol share module after accidental overwrite
restore protocol share module after accidental overwrite
restore protocol share module after accidental overwrite
restore protocol share module after accidental overwrite
restore protocol share module after accidental overwrite
restore protocol share module after accidental overwrite
restore protocol share module after accidental overwrite
restore protocol share module after accidental overwrite
restore protocol share module after accidental overwrite
restore protocol share module after accidental overwrite
restore protocol share module after accidental overwrite
restore protocol share module after accidental overwrite
2026-08-29 15:38:01 +08:00
風雪 e4eecf5462 fix(protocol): patch share error handling 2026-08-29 15:37:44 +08:00
風雪 aff302c36d test(protocol): cover invalid VLESS credential mapping
test(protocol): cover invalid VLESS credential mapping
test(protocol): cover invalid VLESS credential mapping
test(protocol): cover invalid VLESS credential mapping
test(protocol): cover invalid VLESS credential mapping
test(protocol): cover invalid VLESS credential mapping
test(protocol): cover invalid VLESS credential mapping
test(protocol): cover invalid VLESS credential mapping
test(protocol): cover invalid VLESS credential mapping
test(protocol): cover invalid VLESS credential mapping
test(protocol): cover invalid VLESS credential mapping
test(protocol): cover invalid VLESS credential mapping
2026-08-29 15:35:57 +08:00
風雪 4cca1ce9bc fix(protocol): never use password as VLESS UUID 2026-08-29 15:35:48 +08:00
風雪 216c0fca51 test(share): cover Mihomo transport option round-trips
test(share): cover Mihomo transport option round-trips
test(share): cover Mihomo transport option round-trips
test(share): cover Mihomo transport option round-trips
test(share): cover Mihomo transport option round-trips
test(share): cover Mihomo transport option round-trips
test(share): cover Mihomo transport option round-trips
test(share): cover Mihomo transport option round-trips
test(share): cover Mihomo transport option round-trips
test(share): cover Mihomo transport option round-trips
test(share): cover Mihomo transport option round-trips
test(share): cover Mihomo transport option round-trips
2026-08-29 15:30:49 +08:00
風雪 2a71e69611 fix(share): emit Mihomo transport options correctly 2026-08-29 15:30:32 +08:00
風雪 1774ecdaec test(protocol): preserve ALPN in share exports
test(protocol): preserve ALPN in share exports
test(protocol): preserve ALPN in share exports
test(protocol): preserve ALPN in share exports
test(protocol): preserve ALPN in share exports
test(protocol): preserve ALPN in share exports
test(protocol): preserve ALPN in share exports
test(protocol): preserve ALPN in share exports
test(protocol): preserve ALPN in share exports
test(protocol): preserve ALPN in share exports
test(protocol): preserve ALPN in share exports
test(protocol): preserve ALPN in share exports
2026-08-29 15:28:54 +08:00
風雪 54eabcddc8 fix(protocol): preserve ALPN in client share exports 2026-08-29 15:28:42 +08:00
風雪 d4dd1455f1 fix(protocol): decode access-profile ALPN for client shares 2026-08-29 15:28:28 +08:00
風雪 6f0246eb8d fix(protocol): preserve access-profile ALPN in normalized client model 2026-08-29 15:28:16 +08:00
風雪 42fb896a64 test(protocol): cover Reality key consistency and share UDP
test(protocol): cover Reality key consistency and share UDP
test(protocol): cover Reality key consistency and share UDP
test(protocol): cover Reality key consistency and share UDP
test(protocol): cover Reality key consistency and share UDP
test(protocol): cover Reality key consistency and share UDP
test(protocol): cover Reality key consistency and share UDP
test(protocol): cover Reality key consistency and share UDP
test(protocol): cover Reality key consistency and share UDP
test(protocol): cover Reality key consistency and share UDP
test(protocol): cover Reality key consistency and share UDP
test(protocol): cover Reality key consistency and share UDP
2026-08-29 15:26:42 +08:00
風雪 0740011d8e fix(protocol): keep share YAML UDP state and validate Reality key pair 2026-08-29 15:26:32 +08:00
風雪 736164ede2 test(share): tighten REALITY public-key export assertion
test(share): tighten REALITY public-key export assertion
test(share): tighten REALITY public-key export assertion
test(share): tighten REALITY public-key export assertion
test(share): tighten REALITY public-key export assertion
test(share): tighten REALITY public-key export assertion
test(share): tighten REALITY public-key export assertion
test(share): tighten REALITY public-key export assertion
test(share): tighten REALITY public-key export assertion
test(share): tighten REALITY public-key export assertion
test(share): tighten REALITY public-key export assertion
test(share): tighten REALITY public-key export assertion
2026-08-29 15:15:02 +08:00
風雪 bdeec64345 test(share): cover REALITY public-key encoding across exports
test(share): cover REALITY public-key encoding across exports
test(share): cover REALITY public-key encoding across exports
test(share): cover REALITY public-key encoding across exports
test(share): cover REALITY public-key encoding across exports
test(share): cover REALITY public-key encoding across exports
test(share): cover REALITY public-key encoding across exports
test(share): cover REALITY public-key encoding across exports
test(share): cover REALITY public-key encoding across exports
test(share): cover REALITY public-key encoding across exports
test(share): cover REALITY public-key encoding across exports
test(share): cover REALITY public-key encoding across exports
2026-08-29 15:14:40 +08:00
風雪 cef34a5529 fix(share): use URL-safe REALITY public-key encoding 2026-08-29 15:14:14 +08:00
風雪 85463a0936 style: gofmt backend/internal/protocol/types.go
style: gofmt backend/internal/protocol/types.go
style: gofmt backend/internal/protocol/types.go
style: gofmt backend/internal/protocol/types.go
style: gofmt backend/internal/protocol/types.go
style: gofmt backend/internal/protocol/types.go
style: gofmt backend/internal/protocol/types.go
style: gofmt backend/internal/protocol/types.go
style: gofmt backend/internal/protocol/types.go
style: gofmt backend/internal/protocol/types.go
style: gofmt backend/internal/protocol/types.go
style: gofmt backend/internal/protocol/types.go
2026-08-29 11:32:27 +08:00
風雪 5dea855cf1 style: gofmt backend/internal/protocol/share_modules.go
style: gofmt backend/internal/protocol/share_modules.go
style: gofmt backend/internal/protocol/share_modules.go
style: gofmt backend/internal/protocol/share_modules.go
style: gofmt backend/internal/protocol/share_modules.go
style: gofmt backend/internal/protocol/share_modules.go
style: gofmt backend/internal/protocol/share_modules.go
style: gofmt backend/internal/protocol/share_modules.go
style: gofmt backend/internal/protocol/share_modules.go
style: gofmt backend/internal/protocol/share_modules.go
style: gofmt backend/internal/protocol/share_modules.go
style: gofmt backend/internal/protocol/share_modules.go
2026-08-29 11:32:26 +08:00
風雪 74002cc1de style: gofmt backend/internal/protocol/decode.go
style: gofmt backend/internal/protocol/decode.go
style: gofmt backend/internal/protocol/decode.go
style: gofmt backend/internal/protocol/decode.go
style: gofmt backend/internal/protocol/decode.go
style: gofmt backend/internal/protocol/decode.go
style: gofmt backend/internal/protocol/decode.go
style: gofmt backend/internal/protocol/decode.go
style: gofmt backend/internal/protocol/decode.go
style: gofmt backend/internal/protocol/decode.go
style: gofmt backend/internal/protocol/decode.go
style: gofmt backend/internal/protocol/decode.go
2026-08-29 11:32:26 +08:00
風雪 2c44f89516 feat(protocol): strong NodeModel + registry BuildShare () 2026-08-29 00:23:54 +08:00
風雪 39f978b5ec feat(protocol): strong NodeModel + registry BuildShare () 2026-08-29 00:23:53 +08:00
風雪 a36a24e3db feat(protocol): strong NodeModel + registry BuildShare () 2026-08-29 00:23:52 +08:00
風雪 c86f5444a8 feat(protocol): strong NodeModel + registry BuildShare () 2026-08-29 00:23:51 +08:00
風雪 5e6d2eaed9 feat(protocol): strong NodeModel + registry BuildShare () 2026-08-29 00:23:50 +08:00
風雪 6b3a09a09c update
update
update
update
update
update
update
update
update
update
update
update
2026-08-19 12:49:36 +08:00
風雪 fc00113ea5 fix(vless): pair encryption/decryption correctly for TCP Vision
- Stop copying server decryption into client encryption
- Store both fields; strip encryption (client-only) from server Compile
- Form + capability + schema support encryption for subscription export
- Tests for export and compile stripping
fix(vless): pair encryption/decryption correctly for TCP Vision
- Stop copying server decryption into client encryption
- Store both fields; strip encryption (client-only) from server Compile
- Form + capability + schema support encryption for subscription export
- Tests for export and compile stripping
fix(vless): pair encryption/decryption correctly for TCP Vision
- Stop copying server decryption into client encryption
- Store both fields; strip encryption (client-only) from server Compile
- Form + capability + schema support encryption for subscription export
- Tests for export and compile stripping
fix(vless): pair encryption/decryption correctly for TCP Vision
- Stop copying server decryption into client encryption
- Store both fields; strip encryption (client-only) from server Compile
- Form + capability + schema support encryption for subscription export
- Tests for export and compile stripping
fix(vless): pair encryption/decryption correctly for TCP Vision
- Stop copying server decryption into client encryption
- Store both fields; strip encryption (client-only) from server Compile
- Form + capability + schema support encryption for subscription export
- Tests for export and compile stripping
fix(vless): pair encryption/decryption correctly for TCP Vision
- Stop copying server decryption into client encryption
- Store both fields; strip encryption (client-only) from server Compile
- Form + capability + schema support encryption for subscription export
- Tests for export and compile stripping
fix(vless): pair encryption/decryption correctly for TCP Vision
- Stop copying server decryption into client encryption
- Store both fields; strip encryption (client-only) from server Compile
- Form + capability + schema support encryption for subscription export
- Tests for export and compile stripping
fix(vless): pair encryption/decryption correctly for TCP Vision
- Stop copying server decryption into client encryption
- Store both fields; strip encryption (client-only) from server Compile
- Form + capability + schema support encryption for subscription export
- Tests for export and compile stripping
fix(vless): pair encryption/decryption correctly for TCP Vision
- Stop copying server decryption into client encryption
- Store both fields; strip encryption (client-only) from server Compile
- Form + capability + schema support encryption for subscription export
- Tests for export and compile stripping
fix(vless): pair encryption/decryption correctly for TCP Vision
- Stop copying server decryption into client encryption
- Store both fields; strip encryption (client-only) from server Compile
- Form + capability + schema support encryption for subscription export
- Tests for export and compile stripping
fix(vless): pair encryption/decryption correctly for TCP Vision
- Stop copying server decryption into client encryption
- Store both fields; strip encryption (client-only) from server Compile
- Form + capability + schema support encryption for subscription export
- Tests for export and compile stripping
fix(vless): pair encryption/decryption correctly for TCP Vision
- Stop copying server decryption into client encryption
- Store both fields; strip encryption (client-only) from server Compile
- Form + capability + schema support encryption for subscription export
- Tests for export and compile stripping
2026-08-18 14:00:26 +00:00
風雪 94877e6921 test(listener): cover VLESS flow normalization
test(listener): cover VLESS flow normalization
test(listener): cover VLESS flow normalization
test(listener): cover VLESS flow normalization
test(listener): cover VLESS flow normalization
test(listener): cover VLESS flow normalization
test(listener): cover VLESS flow normalization
test(listener): cover VLESS flow normalization
test(listener): cover VLESS flow normalization
test(listener): cover VLESS flow normalization
test(listener): cover VLESS flow normalization
test(listener): cover VLESS flow normalization
2026-08-18 19:03:29 +08:00
風雪 ea71e9f4f3 fix(listener): compile VLESS flow into users 2026-08-18 19:03:19 +08:00
風雪 4212b3ebb7 fix(protocol): pass HasCredentialState into compilers; wire generator 2026-08-18 17:53:10 +08:00
風雪 4c4e3a07ba fix(protocol): honor HasCredentialState; normalize ShadowQUIC object users 2026-08-18 17:52:47 +08:00
風雪 68d9d80a0e feat(protocol): Compile() modules + registry ( modular generation) 2026-08-18 17:09:22 +08:00
風雪 b23af508b6 feat(protocol): capability manifest for VLESS/VMess/Trojan/SS/HY2/TUIC/SQ 2026-08-18 16:57:06 +08:00
風雪 a8c8a52a25 feat(protocol): m-ui capability schema + Access Profile (settings + URI export) 2026-08-18 16:56:35 +08:00