fix(multi-node): scope remote client update/delete to one inbound (#4892)

UpdateUser and DeleteUser hit the node's email-based full-client endpoints, which fanned out to every inbound the client had on the node: editing a client wiped flow on the node's other inbounds, and detaching one node inbound deleted the client from all of them.

Make both inbound-scoped, mirroring AddClient. DeleteUser now detaches the resolved remote inbound id; UpdateUser passes an inboundIds scope so the node updates only that inbound.
This commit is contained in:
MHSanaei
2026-06-04 16:45:40 +02:00
parent a07c7b7f4e
commit db86007ab8
3 changed files with 51 additions and 13 deletions
+16 -3
View File
@@ -634,7 +634,7 @@ func applyShadowsocksClientMethod(clients []any, settings map[string]any) {
}
}
func (s *ClientService) Update(inboundSvc *InboundService, id int, updated model.Client) (bool, error) {
func (s *ClientService) Update(inboundSvc *InboundService, id int, updated model.Client, inboundFilter ...int) (bool, error) {
existing, err := s.GetByID(id)
if err != nil {
return false, err
@@ -643,6 +643,19 @@ func (s *ClientService) Update(inboundSvc *InboundService, id int, updated model
if err != nil {
return false, err
}
if len(inboundFilter) > 0 {
allow := make(map[int]struct{}, len(inboundFilter))
for _, fid := range inboundFilter {
allow[fid] = struct{}{}
}
filtered := inboundIds[:0:0]
for _, ibId := range inboundIds {
if _, ok := allow[ibId]; ok {
filtered = append(filtered, ibId)
}
}
inboundIds = filtered
}
if strings.TrimSpace(updated.Email) == "" {
return false, common.NewError("client email is required")
@@ -1317,7 +1330,7 @@ func (s *ClientService) findInboundIdsByClientEmail(email string) ([]int, error)
return out, nil
}
func (s *ClientService) UpdateByEmail(inboundSvc *InboundService, email string, updated model.Client) (bool, error) {
func (s *ClientService) UpdateByEmail(inboundSvc *InboundService, email string, updated model.Client, inboundFilter ...int) (bool, error) {
if email == "" {
return false, common.NewError("client email is required")
}
@@ -1325,7 +1338,7 @@ func (s *ClientService) UpdateByEmail(inboundSvc *InboundService, email string,
if err != nil {
return false, err
}
return s.Update(inboundSvc, rec.Id, updated)
return s.Update(inboundSvc, rec.Id, updated, inboundFilter...)
}
func (s *ClientService) ResetTrafficByEmail(inboundSvc *InboundService, email string) (bool, error) {