Files
3x-ui/frontend/src/test/__snapshots__/protocols.test.ts.snap
T
MHSanaei 9c8cd08f90 feat(wireguard): multi-client support
WireGuard inbounds now manage per-client peers using xray-core's native WireGuard users (AddUser/RemoveUser). Each client lives in settings.clients (canonical, like every other protocol) and is projected to peers[] only when emitting the xray config, at level 0 so the dispatcher's per-user traffic/online counters work with no extra plumbing.

Backend: internal/util/wireguard gains KeyToHex (base64 to hex for the gRPC path), PublicKeyFromPrivate and GenerateWireguardPSK; xray/api.go builds a wireguard account in AddUser with hex keys (RemoveUser already worked); client CRUD generates a keypair and allocates a unique tunnel address per client and never rotates keys on edit; an idempotent migration converts legacy settings.peers into managed clients; WireGuard is included in the raw subscription.

Frontend: WireGuard in the add-client modal with keys on the credential tab, client schema, per-client QR/link/.conf, inbound form reduced to server settings; i18n added across 13 locales.

Fix: guard the settings[clients] assertion in add/update so a legacy WireGuard inbound stored without a clients key no longer panics.
2026-06-28 00:44:38 +02:00

227 lines
4.8 KiB
Plaintext

// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`InboundSettingsSchema fixtures > parses http-basic byte-stably 1`] = `
{
"protocol": "http",
"settings": {
"accounts": [
{
"pass": "proxypass",
"user": "proxyuser",
},
{
"pass": "guest123",
"user": "guest",
},
],
"allowTransparent": false,
},
}
`;
exports[`InboundSettingsSchema fixtures > parses hysteria-basic byte-stably 1`] = `
{
"protocol": "hysteria",
"settings": {
"clients": [
{
"auth": "hyst3ria-v1-token-XYZ",
"comment": "legacy v1",
"email": "hy1-client@example.test",
"enable": true,
"expiryTime": 0,
"limitIp": 0,
"reset": 0,
"subId": "hy1-001",
"tgId": 0,
"totalGB": 0,
},
],
"version": 1,
},
}
`;
exports[`InboundSettingsSchema fixtures > parses mixed-basic byte-stably 1`] = `
{
"protocol": "mixed",
"settings": {
"accounts": [
{
"pass": "sockspass",
"user": "socksuser",
},
],
"auth": "password",
"ip": "127.0.0.1",
"udp": true,
},
}
`;
exports[`InboundSettingsSchema fixtures > parses mtproto-basic byte-stably 1`] = `
{
"protocol": "mtproto",
"settings": {
"fakeTlsDomain": "www.cloudflare.com",
"secret": "ee0123456789abcdef0123456789abcdef7777772e636c6f7564666c6172652e636f6d",
},
}
`;
exports[`InboundSettingsSchema fixtures > parses mtproto-domain-fronting byte-stably 1`] = `
{
"protocol": "mtproto",
"settings": {
"debug": true,
"domainFronting": {
"ip": "127.0.0.1",
"port": 9443,
"proxyProtocol": true,
},
"fakeTlsDomain": "www.cloudflare.com",
"preferIp": "prefer-ipv4",
"proxyProtocolListener": true,
"secret": "ee0123456789abcdef0123456789abcdef7777772e636c6f7564666c6172652e636f6d",
},
}
`;
exports[`InboundSettingsSchema fixtures > parses shadowsocks-2022 byte-stably 1`] = `
{
"protocol": "shadowsocks",
"settings": {
"clients": [
{
"comment": "multi-user shadowsocks 2022",
"email": "ss-client-1@example.test",
"enable": true,
"expiryTime": 0,
"limitIp": 0,
"method": "",
"password": "dGVzdC1jbGllbnQtcGFzc3dvcmQtMQ==",
"reset": 0,
"subId": "ssm001",
"tgId": 0,
"totalGB": 0,
},
],
"ivCheck": false,
"method": "2022-blake3-aes-256-gcm",
"network": "tcp,udp",
"password": "9oCBhTZxJ5wQa3fLs2vK7nM6pR4tY1uX",
},
}
`;
exports[`InboundSettingsSchema fixtures > parses trojan-basic byte-stably 1`] = `
{
"protocol": "trojan",
"settings": {
"clients": [
{
"comment": "",
"email": "carol@example.test",
"enable": true,
"expiryTime": 0,
"limitIp": 0,
"password": "tr0jan-passw0rd-XyZ-123!",
"reset": 0,
"subId": "trj001",
"tgId": 0,
"totalGB": 0,
},
],
"fallbacks": [],
},
}
`;
exports[`InboundSettingsSchema fixtures > parses tunnel-basic byte-stably 1`] = `
{
"protocol": "tunnel",
"settings": {
"allowedNetwork": "tcp,udp",
"followRedirect": false,
"portMap": {
"8080": "10.0.0.5:80",
"8443": "10.0.0.5:443",
},
"rewriteAddress": "1.1.1.1",
"rewritePort": 53,
},
}
`;
exports[`InboundSettingsSchema fixtures > parses vless-tcp-none byte-stably 1`] = `
{
"protocol": "vless",
"settings": {
"clients": [
{
"comment": "",
"email": "alice@example.test",
"enable": true,
"expiryTime": 0,
"flow": "",
"id": "8c14d6f7-2e3b-4a91-9d24-3f7a6b8c1e02",
"limitIp": 0,
"reset": 0,
"subId": "abc123def",
"tgId": 0,
"totalGB": 0,
},
],
"decryption": "none",
"encryption": "none",
"fallbacks": [],
},
}
`;
exports[`InboundSettingsSchema fixtures > parses vmess-basic byte-stably 1`] = `
{
"protocol": "vmess",
"settings": {
"clients": [
{
"alterId": 0,
"comment": "primary tester",
"email": "bob@example.test",
"enable": true,
"expiryTime": 0,
"id": "c0aa1b9e-4d56-4e8b-9a01-bf2e5d7c4f31",
"limitIp": 2,
"reset": 0,
"security": "auto",
"subId": "vmess001",
"tgId": 0,
"totalGB": 0,
},
],
},
}
`;
exports[`InboundSettingsSchema fixtures > parses wireguard-basic byte-stably 1`] = `
{
"protocol": "wireguard",
"settings": {
"clients": [],
"mtu": 1420,
"noKernelTun": false,
"peers": [
{
"allowedIPs": [
"10.0.0.2/32",
],
"keepAlive": 25,
"privateKey": "iJ2cBkrSGqRwIfYIDIxk7hr5RXfdR93MfJUL7yqkkH8=",
"publicKey": "DGSYIcEKAUkA7HhzGSjxLZuV67BR3LeyU0BMLJzNVHQ=",
},
],
"secretKey": "QGVlb2dXc1ZTWGw0ZXBzZndsWmtMaUM5MUlNYjBHWFdYbz0=",
},
}
`;