mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-15 10:25:00 +03:00
fix(inbounds): keep the stored client list and enable on inbound save
Invariant: saving an inbound's configuration never changes which clients it holds nor whether it is enabled; both have their own endpoints. The edit modal posts back the clients and the enable flag it loaded when it opened. A client added meanwhile (another admin, the bot, the API, LDAP) was detached and its stats deleted; a client deleted meanwhile came back with its credentials, restoring access that had been revoked; an inbound switched off meanwhile was switched back on. For every save but a master's node-sync push, UpdateInbound now takes the client list and enable from the row it re-reads inside the writer; this replaces the lifecycle-only carry from the previous commit. Client validation (renewal schedule, Hysteria auth, TUIC credentials) moves after that swap so it judges the clients actually saved: a protocol switch keeps the stored clients, and #6268's refusal must apply to them. The edit form no longer loads or sends clients, so neither the JSON editor nor validation sees a copy the server ignores, and the enable switch shows only when adding; the list toggle (/setEnable) covers existing inbounds. Tests that added or re-keyed clients through a panel inbound save pinned the old rule; they now drive the master-push path, where payload clients still apply.
This commit is contained in:
@@ -353,9 +353,22 @@ export function dropLegacyOptionalEmpties(
|
||||
}
|
||||
}
|
||||
|
||||
export function formValuesToWirePayload(values: InboundFormValues): WireInboundPayload {
|
||||
// An existing inbound's clients change only through the client endpoints, so
|
||||
// the edit form neither loads them nor sends them back.
|
||||
export function withoutClients(values: InboundFormValues): InboundFormValues {
|
||||
const settings = { ...(values.settings as Record<string, unknown> | undefined) };
|
||||
delete settings.clients;
|
||||
return { ...values, settings } as InboundFormValues;
|
||||
}
|
||||
|
||||
export function formValuesToWirePayload(
|
||||
values: InboundFormValues,
|
||||
options: { omitClients?: boolean } = {},
|
||||
): WireInboundPayload {
|
||||
const settingsPruned = (pruneEmpty(values.settings ?? {}) ?? {}) as Record<string, unknown>;
|
||||
if (Array.isArray(settingsPruned.clients)) {
|
||||
if (options.omitClients) {
|
||||
delete settingsPruned.clients;
|
||||
} else if (Array.isArray(settingsPruned.clients)) {
|
||||
settingsPruned.clients = normalizeClients(values.protocol, settingsPruned.clients);
|
||||
}
|
||||
let streamPruned = values.streamSettings
|
||||
|
||||
Reference in New Issue
Block a user