mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-23 03:17:14 +00:00
feat(sub): add per-client subscription HWID limits (#5802)
* feat(sub): add per-client subscription HWID limits * fix(sub): address HWID review on shared subId and bulk create * fix(sub): store HWID devices by sub_id and drop anchor client workaround * fix(sub): restore UA auto-detect and HTML page routing in subs() The cherry-pick of the HWID gate onto main's refactored SUBController had dropped main's UA-based format auto-detection and sub-page handling from subs(). Restore those branches, slotting enforceHwid after the HTML page and before format detection so the gate only applies to machine-readable subscription bodies. Also adapt tests to main's options-struct constructor and to the ClientService.Update signature extended with limitHwid. * fix(frontend): drop axios from HttpUtil.delete The bulk-delete rework's committed version still referenced axios, which this file no longer imports, breaking typecheck in CI. Use the httpRequest wrapper like the other verbs. --------- Co-authored-by: Sanaei <ho3ein.sanaei@gmail.com>
This commit is contained in:
@@ -816,6 +816,7 @@ func (s *ClientService) BulkDelete(inboundSvc *InboundService, emails []string,
|
||||
successEmails := make([]string, 0, len(recordsByEmail))
|
||||
successIds := make([]int, 0, len(recordsByEmail))
|
||||
failedEmails := make([]string, 0, len(recordsByEmail))
|
||||
successSubIDs := make([]string, 0, len(recordsByEmail))
|
||||
for email, rec := range recordsByEmail {
|
||||
if _, skipped := skippedReasons[email]; skipped {
|
||||
failedEmails = append(failedEmails, email)
|
||||
@@ -823,6 +824,7 @@ func (s *ClientService) BulkDelete(inboundSvc *InboundService, emails []string,
|
||||
}
|
||||
successEmails = append(successEmails, email)
|
||||
successIds = append(successIds, rec.Id)
|
||||
successSubIDs = append(successSubIDs, rec.SubID)
|
||||
}
|
||||
withdrawClientTombstones(failedEmails...)
|
||||
|
||||
@@ -833,6 +835,9 @@ func (s *ClientService) BulkDelete(inboundSvc *InboundService, emails []string,
|
||||
if e := adjustGroupBaselinesForRemovedTraffic(tx, successEmails); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := clearClientHwidsBySubIDTx(tx, successSubIDs...); e != nil {
|
||||
return e
|
||||
}
|
||||
for _, batch := range chunkInts(successIds, sqlInChunk) {
|
||||
if e := tx.Where("client_id IN ?", batch).Delete(&model.ClientInbound{}).Error; e != nil {
|
||||
return e
|
||||
@@ -1119,6 +1124,7 @@ func (s *ClientService) BulkCreate(inboundSvc *InboundService, payloads []Client
|
||||
type prepared struct {
|
||||
client model.Client
|
||||
inboundIds []int
|
||||
limitHwid int
|
||||
}
|
||||
prep := make([]prepared, 0, len(payloads))
|
||||
emails := make([]string, 0, len(payloads))
|
||||
@@ -1171,7 +1177,7 @@ func (s *ClientService) BulkCreate(inboundSvc *InboundService, payloads []Client
|
||||
seenEmail[le] = struct{}{}
|
||||
seenSubID[client.SubID] = le
|
||||
|
||||
prep = append(prep, prepared{client: client, inboundIds: payloads[i].InboundIds})
|
||||
prep = append(prep, prepared{client: client, inboundIds: payloads[i].InboundIds, limitHwid: payloads[i].LimitHwid})
|
||||
emails = append(emails, email)
|
||||
subIDs = append(subIDs, client.SubID)
|
||||
}
|
||||
@@ -1303,9 +1309,13 @@ func (s *ClientService) BulkCreate(inboundSvc *InboundService, payloads []Client
|
||||
for idx := range prep {
|
||||
if failed[idx] {
|
||||
skip(prep[idx].client.Email, reason[idx])
|
||||
} else {
|
||||
result.Created++
|
||||
continue
|
||||
}
|
||||
if err := s.setClientLimitHwidByEmail(nil, prep[idx].client.Email, prep[idx].limitHwid); err != nil {
|
||||
skip(prep[idx].client.Email, err.Error())
|
||||
continue
|
||||
}
|
||||
result.Created++
|
||||
}
|
||||
return result, needRestart, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user