fix(ldap): keep expired and over-quota clients off on directory sync

The LDAP sync enabled every disabled client whose directory flag was
true, without asking why it was off. A client the traffic job had just
disabled for a passed expiry or a spent quota therefore came back on
every sync and connected again for the seconds until the next traffic
pass, for as long as the directory listed it.

The sync's enable step now drops the clients the panel's own depletion
rule keeps off, and enables nobody in a run whose lookup fails. A
client the operator renews is enabled at the next sync.
This commit is contained in:
MHSanaei
2026-11-01 00:44:05 +01:00
parent c92c7718bf
commit bebe1b911d
3 changed files with 108 additions and 0 deletions
+21
View File
@@ -6,6 +6,7 @@ import (
"strconv"
"time"
"github.com/mhsanaei/3x-ui/v3/internal/database"
"github.com/mhsanaei/3x-ui/v3/internal/database/model"
"github.com/mhsanaei/3x-ui/v3/internal/logger"
"github.com/mhsanaei/3x-ui/v3/internal/xray"
@@ -267,3 +268,23 @@ func trafficDisabledEmails(db *gorm.DB, emails []string) (map[string]struct{}, e
}
return disabled, nil
}
// DepletedClientEmails reports which emails disableInvalidClients keeps off (quota
// spent or expiry passed), so an unattended enable does not hand them back.
func (s *InboundService) DepletedClientEmails(emails []string) (map[string]struct{}, error) {
db := database.GetDB()
cond, condArgs := depletedCond(db)
depleted := make(map[string]struct{})
for _, batch := range chunkStrings(uniqueNonEmptyStrings(emails), sqlInChunk) {
var page []string
if err := db.Model(xray.ClientTraffic{}).
Where(cond+" AND email IN ?", append(append([]any{}, condArgs...), batch)...).
Pluck("email", &page).Error; err != nil {
return nil, err
}
for _, e := range page {
depleted[e] = struct{}{}
}
}
return depleted, nil
}