From c4a1139d3fce12f8f4d146efd841b69822735b13 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sun, 12 Jul 2026 15:31:27 +0200 Subject: [PATCH] feat(frontend): treat wireguard inbounds as multi-user in client actions WireGuard has been first-class multi-client on the backend for a while (key generation, tunnel address allocation, attach/detach/delete all flow through the shared client apply path), but isInboundMultiUser still excluded it, so wireguard rows only offered Export Inbound / Reset Traffic / Clone / Delete. Adding it to the multi-user set surfaces Export All URLs (per-client .conf blocks), the subscription export, and the attach/detach/group/delete-all client actions, and makes wireguard inbounds valid targets in the attach-clients picker. The now-dead isWireguard guard on the inbound-info branch is dropped. The clients-page bulk attach/detach modals carried the same stale protocol set, also missing mtproto, so both now match the single-client form's inbound picker. --- frontend/src/pages/clients/BulkAttachInboundsModal.tsx | 2 +- frontend/src/pages/clients/BulkDetachInboundsModal.tsx | 2 +- frontend/src/pages/inbounds/list/RowActions.tsx | 2 +- frontend/src/pages/inbounds/list/helpers.ts | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/clients/BulkAttachInboundsModal.tsx b/frontend/src/pages/clients/BulkAttachInboundsModal.tsx index f3d4ecf3f..31a74ab62 100644 --- a/frontend/src/pages/clients/BulkAttachInboundsModal.tsx +++ b/frontend/src/pages/clients/BulkAttachInboundsModal.tsx @@ -7,7 +7,7 @@ import type { InboundOption } from '@/hooks/useClients'; import { formatInboundLabel } from '@/lib/inbounds/label'; import type { BulkAttachResult } from '@/schemas/client'; -const MULTI_USER_PROTOCOLS = new Set(['vmess', 'vless', 'trojan', 'hysteria', 'shadowsocks']); +const MULTI_USER_PROTOCOLS = new Set(['vmess', 'vless', 'trojan', 'hysteria', 'shadowsocks', 'wireguard', 'mtproto']); interface BulkAttachInboundsModalProps { open: boolean; diff --git a/frontend/src/pages/clients/BulkDetachInboundsModal.tsx b/frontend/src/pages/clients/BulkDetachInboundsModal.tsx index 66eb31bd4..93835c220 100644 --- a/frontend/src/pages/clients/BulkDetachInboundsModal.tsx +++ b/frontend/src/pages/clients/BulkDetachInboundsModal.tsx @@ -7,7 +7,7 @@ import type { InboundOption } from '@/hooks/useClients'; import { formatInboundLabel } from '@/lib/inbounds/label'; import type { BulkDetachResult } from '@/schemas/client'; -const MULTI_USER_PROTOCOLS = new Set(['vmess', 'vless', 'trojan', 'hysteria', 'shadowsocks']); +const MULTI_USER_PROTOCOLS = new Set(['vmess', 'vless', 'trojan', 'hysteria', 'shadowsocks', 'wireguard', 'mtproto']); interface BulkDetachInboundsModalProps { open: boolean; diff --git a/frontend/src/pages/inbounds/list/RowActions.tsx b/frontend/src/pages/inbounds/list/RowActions.tsx index 6e33d961a..120d1dbcb 100644 --- a/frontend/src/pages/inbounds/list/RowActions.tsx +++ b/frontend/src/pages/inbounds/list/RowActions.tsx @@ -43,7 +43,7 @@ export function buildRowActionsMenu({ record, subEnable, t, isMobile, hasClients label: `${t('pages.inbounds.export')} — ${t('pages.settings.subSettings')}`, }); } - } else if (!record.isWireguard) { + } else { items.push({ key: 'showInfo', icon: , label: t('pages.inbounds.inboundInfo') }); } items.push({ key: 'clipboard', icon: , label: t('pages.inbounds.exportInbound') }); diff --git a/frontend/src/pages/inbounds/list/helpers.ts b/frontend/src/pages/inbounds/list/helpers.ts index 21b140e4c..3f63648ba 100644 --- a/frontend/src/pages/inbounds/list/helpers.ts +++ b/frontend/src/pages/inbounds/list/helpers.ts @@ -73,6 +73,7 @@ export function isInboundMultiUser(record: { protocol: string; settings: unknown case 'trojan': case 'hysteria': case 'mtproto': + case 'wireguard': return true; case 'shadowsocks': return isSSMultiUser({ protocol: 'shadowsocks', settings: readSettings(record.settings) });