mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-05-30 00:49:34 +00:00
fix(clients): avoid duplicate ClientRecord when email is changed on edit
SyncInbound (invoked from UpdateInboundClient during a client edit) looks up the ClientRecord row by the email present in the inbound's settings. After an email change the lookup misses the original row, hits the gorm.ErrRecordNotFound branch, and inserts a fresh ClientRecord with the new email. The original row stays in place with its inbound link cleared, so the clients list shows both — the original as an orphan and the new one as if it had just been created. Rename the existing ClientRecord row to the new email up front, before the inbound loop runs. SyncInbound then finds and updates the same row instead of creating a duplicate. A pre-check rejects renames that would collide with another client's email so the unique index keeps its meaning.
This commit is contained in:
@@ -595,6 +595,27 @@ func (s *ClientService) Update(inboundSvc *InboundService, id int, updated model
|
||||
updated.CreatedAt = existing.CreatedAt
|
||||
}
|
||||
|
||||
// Rename the ClientRecord row up front when the email changes. SyncInbound
|
||||
// (invoked from UpdateInboundClient below) looks up by email — without
|
||||
// renaming first it would treat the new email as a brand-new client,
|
||||
// insert a duplicate ClientRecord, and leave the original orphaned.
|
||||
if updated.Email != existing.Email {
|
||||
var collisionCount int64
|
||||
if err := database.GetDB().Model(&model.ClientRecord{}).
|
||||
Where("email = ? AND id <> ?", updated.Email, id).
|
||||
Count(&collisionCount).Error; err != nil {
|
||||
return false, err
|
||||
}
|
||||
if collisionCount > 0 {
|
||||
return false, common.NewError("Duplicate email:", updated.Email)
|
||||
}
|
||||
if err := database.GetDB().Model(&model.ClientRecord{}).
|
||||
Where("id = ?", id).
|
||||
Update("email", updated.Email).Error; err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
needRestart := false
|
||||
for _, ibId := range inboundIds {
|
||||
inbound, getErr := inboundSvc.GetInbound(ibId)
|
||||
|
||||
Reference in New Issue
Block a user