simplify API calls #218

This commit is contained in:
Alireza Ahmadi
2023-04-18 01:22:33 +02:00
parent 0c755be648
commit f4f8c0d6df
5 changed files with 130 additions and 82 deletions

View File

@@ -31,7 +31,7 @@ func (a *InboundController) initRouter(g *gin.RouterGroup) {
g.POST("/add", a.addInbound) g.POST("/add", a.addInbound)
g.POST("/del/:id", a.delInbound) g.POST("/del/:id", a.delInbound)
g.POST("/update/:id", a.updateInbound) g.POST("/update/:id", a.updateInbound)
g.POST("/addClient/", a.addInboundClient) g.POST("/addClient", a.addInboundClient)
g.POST("/delClient/:email", a.delInboundClient) g.POST("/delClient/:email", a.delInboundClient)
g.POST("/updateClient/:index", a.updateInboundClient) g.POST("/updateClient/:index", a.updateInboundClient)
g.POST("/:id/resetClientTraffic/:email", a.resetClientTraffic) g.POST("/:id/resetClientTraffic/:email", a.resetClientTraffic)
@@ -129,19 +129,19 @@ func (a *InboundController) updateInbound(c *gin.Context) {
} }
func (a *InboundController) addInboundClient(c *gin.Context) { func (a *InboundController) addInboundClient(c *gin.Context) {
inbound := &model.Inbound{} data := &model.Inbound{}
err := c.ShouldBind(inbound) err := c.ShouldBind(data)
if err != nil { if err != nil {
jsonMsg(c, I18n(c, "pages.inbounds.revise"), err) jsonMsg(c, I18n(c, "pages.inbounds.revise"), err)
return return
} }
err = a.inboundService.AddInboundClient(inbound) err = a.inboundService.AddInboundClient(data)
if err != nil { if err != nil {
jsonMsg(c, "something worng!", err) jsonMsg(c, "something worng!", err)
return return
} }
jsonMsg(c, "Client added", nil) jsonMsg(c, "Client(s) added", nil)
if err == nil { if err == nil {
a.xrayService.SetToNeedRestart() a.xrayService.SetToNeedRestart()
} }

View File

@@ -150,7 +150,6 @@
confirm: null, confirm: null,
dbInbound: new DBInbound(), dbInbound: new DBInbound(),
inbound: new Inbound(), inbound: new Inbound(),
clients: [],
quantity: 1, quantity: 1,
totalGB: 0, totalGB: 0,
expiryTime: '', expiryTime: '',
@@ -164,6 +163,7 @@
flow: "", flow: "",
delayedStart: false, delayedStart: false,
ok() { ok() {
clients = [];
method=clientsBulkModal.emailMethod; method=clientsBulkModal.emailMethod;
if(method>1){ if(method>1){
start=clientsBulkModal.firstNum; start=clientsBulkModal.firstNum;
@@ -186,9 +186,9 @@
if(clientsBulkModal.inbound.canEnableTlsFlow()){ if(clientsBulkModal.inbound.canEnableTlsFlow()){
newClient.flow = clientsBulkModal.flow; newClient.flow = clientsBulkModal.flow;
} }
clientsBulkModal.clients.push(newClient); clients.push(newClient);
} }
ObjectUtil.execute(clientsBulkModal.confirm, clientsBulkModal.inbound, clientsBulkModal.dbInbound); ObjectUtil.execute(clientsBulkModal.confirm, clients, clientsBulkModal.dbInbound.id);
}, },
show({ title='', okText='{{ i18n "sure" }}', dbInbound=null, confirm=(inbound, dbInbound)=>{} }) { show({ title='', okText='{{ i18n "sure" }}', dbInbound=null, confirm=(inbound, dbInbound)=>{} }) {
this.visible = true; this.visible = true;
@@ -208,7 +208,6 @@
this.flow= ""; this.flow= "";
this.dbInbound = new DBInbound(dbInbound); this.dbInbound = new DBInbound(dbInbound);
this.inbound = dbInbound.toInbound(); this.inbound = dbInbound.toInbound();
this.clients = this.getClients(this.inbound.protocol, this.inbound.settings);
this.delayedStart = false; this.delayedStart = false;
}, },
getClients(protocol, clientSettings) { getClients(protocol, clientSettings) {

View File

@@ -12,6 +12,7 @@
confirmLoading: false, confirmLoading: false,
title: '', title: '',
okText: '', okText: '',
isEdit: false,
dbInbound: new DBInbound(), dbInbound: new DBInbound(),
inbound: new Inbound(), inbound: new Inbound(),
clients: [], clients: [],
@@ -20,9 +21,13 @@
isExpired: false, isExpired: false,
delayedStart: false, delayedStart: false,
ok() { ok() {
ObjectUtil.execute(clientModal.confirm, clientModal.inbound, clientModal.dbInbound, clientModal.index); if(clientModal.isEdit){
ObjectUtil.execute(clientModal.confirm, clientModalApp.client, clientModal.dbInbound.id, clientModal.index);
} else {
ObjectUtil.execute(clientModal.confirm, clientModalApp.client, clientModal.dbInbound.id);
}
}, },
show({ title='', okText='{{ i18n "sure" }}', index=null, dbInbound=null, confirm=(index, dbInbound)=>{}, isEdit=false }) { show({ title='', okText='{{ i18n "sure" }}', index=null, dbInbound=null, confirm=()=>{}, isEdit=false }) {
this.visible = true; this.visible = true;
this.title = title; this.title = title;
this.okText = okText; this.okText = okText;

View File

@@ -209,11 +209,10 @@
</a-layout> </a-layout>
{{template "js" .}} {{template "js" .}}
<script> <script>
const columns = [{ const columns = [{
title: '{{ i18n "pages.inbounds.operate" }}', title: '{{ i18n "pages.inbounds.operate" }}',
align: 'center', align: 'center',
width: 30, width: 40,
scopedSlots: { customRender: 'action' }, scopedSlots: { customRender: 'action' },
}, { }, {
title: '{{ i18n "pages.inbounds.enable" }}', title: '{{ i18n "pages.inbounds.enable" }}',
@@ -221,7 +220,7 @@
width: 40, width: 40,
scopedSlots: { customRender: 'enable' }, scopedSlots: { customRender: 'enable' },
}, { }, {
title: "Id", title: "ID",
align: 'center', align: 'center',
dataIndex: "id", dataIndex: "id",
width: 30, width: 30,
@@ -529,9 +528,9 @@
title: '{{ i18n "pages.client.add"}}', title: '{{ i18n "pages.client.add"}}',
okText: '{{ i18n "pages.client.submitAdd"}}', okText: '{{ i18n "pages.client.submitAdd"}}',
dbInbound: dbInbound, dbInbound: dbInbound,
confirm: async (inbound, dbInbound, index) => { confirm: async (clients, dbInboundId) => {
clientModal.loading(); clientModal.loading();
await this.addClient(inbound, dbInbound); await this.addClient(clients, dbInboundId);
clientModal.close(); clientModal.close();
}, },
isEdit: false isEdit: false
@@ -543,9 +542,9 @@
title: '{{ i18n "pages.client.bulk"}} ' + dbInbound.remark, title: '{{ i18n "pages.client.bulk"}} ' + dbInbound.remark,
okText: '{{ i18n "pages.client.bulk"}}', okText: '{{ i18n "pages.client.bulk"}}',
dbInbound: dbInbound, dbInbound: dbInbound,
confirm: async (inbound, dbInbound) => { confirm: async (clients, dbInboundId) => {
clientsBulkModal.loading(); clientsBulkModal.loading();
await this.addClient(inbound, dbInbound); await this.addClient(clients, dbInboundId);
clientsBulkModal.close(); clientsBulkModal.close();
}, },
}); });
@@ -559,9 +558,9 @@
okText: '{{ i18n "pages.client.submitEdit"}}', okText: '{{ i18n "pages.client.submitEdit"}}',
dbInbound: dbInbound, dbInbound: dbInbound,
index: index, index: index,
confirm: async (inbound, dbInbound, index) => { confirm: async (client, dbInboundId, index) => {
clientModal.loading(); clientModal.loading();
await this.updateClient(inbound, dbInbound, index); await this.updateClient(client, dbInboundId, index);
clientModal.close(); clientModal.close();
}, },
isEdit: true isEdit: true
@@ -571,17 +570,17 @@
firstKey = Object.keys(client)[0]; firstKey = Object.keys(client)[0];
return clients.findIndex(c => c[firstKey] === client[firstKey]); return clients.findIndex(c => c[firstKey] === client[firstKey]);
}, },
async addClient(inbound, dbInbound) { async addClient(clients, dbInboundId) {
const data = { const data = {
id: dbInbound.id, id: dbInboundId,
settings: inbound.settings.toString(), settings: '{"clients": [' + clients.toString() +']}',
}; };
await this.submit('/xui/inbound/addClient/', data); await this.submit(`/xui/inbound/addClient`, data);
}, },
async updateClient(inbound, dbInbound, index) { async updateClient(client, dbInboundId, index) {
const data = { const data = {
id: dbInbound.id, id: dbInboundId,
settings: inbound.settings.toString(), settings: '{"clients": [' + client.toString() +']}',
}; };
await this.submit(`/xui/inbound/updateClient/${index}`, data); await this.submit(`/xui/inbound/updateClient/${index}`, data);
}, },

View File

@@ -64,28 +64,45 @@ func (s *InboundService) getClients(inbound *model.Inbound) ([]model.Client, err
return clients, nil return clients, nil
} }
func (s *InboundService) checkEmailsExist(emails map[string]bool, ignoreId int) (string, error) { func (s *InboundService) getAllEmails() ([]string, error) {
db := database.GetDB() db := database.GetDB()
var inbounds []*model.Inbound var emails []string
db = db.Model(model.Inbound{}).Where("Protocol in ?", []model.Protocol{model.VMess, model.VLESS, model.Trojan}) err := db.Raw(`
if ignoreId > 0 { SELECT JSON_EXTRACT(client.value, '$.email')
db = db.Where("id != ?", ignoreId) FROM inbounds,
} JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client
db = db.Find(&inbounds) `).Scan(&emails).Error
if db.Error != nil {
return "", db.Error
}
for _, inbound := range inbounds { if err != nil {
clients, err := s.getClients(inbound) return nil, err
if err != nil { }
return "", err return emails, nil
}
func (s *InboundService) contains(slice []string, str string) bool {
for _, s := range slice {
if s == str {
return true
} }
}
return false
}
for _, client := range clients { func (s *InboundService) checkEmailsExistForClients(clients []model.Client) (string, error) {
if emails[client.Email] { allEmails, err := s.getAllEmails()
if err != nil {
return "", err
}
var emails []string
for _, client := range clients {
if client.Email != "" {
if s.contains(emails, client.Email) {
return client.Email, nil return client.Email, nil
} }
if s.contains(allEmails, client.Email) {
return client.Email, nil
}
emails = append(emails, client.Email)
} }
} }
return "", nil return "", nil
@@ -96,16 +113,23 @@ func (s *InboundService) checkEmailExistForInbound(inbound *model.Inbound) (stri
if err != nil { if err != nil {
return "", err return "", err
} }
emails := make(map[string]bool) allEmails, err := s.getAllEmails()
if err != nil {
return "", err
}
var emails []string
for _, client := range clients { for _, client := range clients {
if client.Email != "" { if client.Email != "" {
if emails[client.Email] { if s.contains(emails, client.Email) {
return client.Email, nil return client.Email, nil
} }
emails[client.Email] = true if s.contains(allEmails, client.Email) {
return client.Email, nil
}
emails = append(emails, client.Email)
} }
} }
return s.checkEmailsExist(emails, inbound.Id) return "", nil
} }
func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound, error) { func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound, error) {
@@ -201,14 +225,6 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound,
return inbound, common.NewError("Port already exists:", inbound.Port) return inbound, common.NewError("Port already exists:", inbound.Port)
} }
existEmail, err := s.checkEmailExistForInbound(inbound)
if err != nil {
return inbound, err
}
if existEmail != "" {
return inbound, common.NewError("Duplicate email:", existEmail)
}
oldInbound, err := s.GetInbound(inbound.Id) oldInbound, err := s.GetInbound(inbound.Id)
if err != nil { if err != nil {
return inbound, err return inbound, err
@@ -231,8 +247,12 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound,
return inbound, db.Save(oldInbound).Error return inbound, db.Save(oldInbound).Error
} }
func (s *InboundService) AddInboundClient(inbound *model.Inbound) error { func (s *InboundService) AddInboundClient(data *model.Inbound) error {
existEmail, err := s.checkEmailExistForInbound(inbound) clients, err := s.getClients(data)
if err != nil {
return err
}
existEmail, err := s.checkEmailsExistForClients(clients)
if err != nil { if err != nil {
return err return err
} }
@@ -241,29 +261,35 @@ func (s *InboundService) AddInboundClient(inbound *model.Inbound) error {
return common.NewError("Duplicate email:", existEmail) return common.NewError("Duplicate email:", existEmail)
} }
clients, err := s.getClients(inbound) oldInbound, err := s.GetInbound(data.Id)
if err != nil { if err != nil {
return err return err
} }
oldInbound, err := s.GetInbound(inbound.Id) var settings map[string]interface{}
err = json.Unmarshal([]byte(oldInbound.Settings), &settings)
if err != nil { if err != nil {
return err return err
} }
oldClients, err := s.getClients(oldInbound) oldClients := settings["clients"].([]interface{})
var newClients []interface{}
for _, client := range clients {
newClients = append(newClients, client)
}
settings["clients"] = append(oldClients, newClients...)
newSettings, err := json.MarshalIndent(settings, "", " ")
if err != nil { if err != nil {
return err return err
} }
oldInbound.Settings = inbound.Settings oldInbound.Settings = string(newSettings)
if len(clients[len(clients)-1].Email) > 0 { for _, client := range clients {
s.AddClientStat(inbound.Id, &clients[len(clients)-1]) if len(client.Email) > 0 {
} s.AddClientStat(data.Id, &client)
for i := len(oldClients); i < len(clients); i++ {
if len(clients[i].Email) > 0 {
s.AddClientStat(inbound.Id, &clients[i])
} }
} }
db := database.GetDB() db := database.GetDB()
@@ -289,21 +315,13 @@ func (s *InboundService) DelInboundClient(inbound *model.Inbound, email string)
return db.Save(oldInbound).Error return db.Save(oldInbound).Error
} }
func (s *InboundService) UpdateInboundClient(inbound *model.Inbound, index int) error { func (s *InboundService) UpdateInboundClient(data *model.Inbound, index int) error {
existEmail, err := s.checkEmailExistForInbound(inbound) clients, err := s.getClients(data)
if err != nil {
return err
}
if existEmail != "" {
return common.NewError("Duplicate email:", existEmail)
}
clients, err := s.getClients(inbound)
if err != nil { if err != nil {
return err return err
} }
oldInbound, err := s.GetInbound(inbound.Id) oldInbound, err := s.GetInbound(data.Id)
if err != nil { if err != nil {
return err return err
} }
@@ -313,18 +331,45 @@ func (s *InboundService) UpdateInboundClient(inbound *model.Inbound, index int)
return err return err
} }
oldInbound.Settings = inbound.Settings if len(clients[0].Email) > 0 && clients[0].Email != oldClients[index].Email {
existEmail, err := s.checkEmailsExistForClients(clients)
if err != nil {
return err
}
if existEmail != "" {
return common.NewError("Duplicate email:", existEmail)
}
}
var settings map[string]interface{}
err = json.Unmarshal([]byte(oldInbound.Settings), &settings)
if err != nil {
return err
}
settingsClients := settings["clients"].([]interface{})
var newClients []interface{}
newClients = append(newClients, clients[0])
settingsClients[index] = newClients[0]
settings["clients"] = settingsClients
newSettings, err := json.MarshalIndent(settings, "", " ")
if err != nil {
return err
}
oldInbound.Settings = string(newSettings)
db := database.GetDB() db := database.GetDB()
if len(clients[index].Email) > 0 { if len(clients[0].Email) > 0 {
if len(oldClients[index].Email) > 0 { if len(oldClients[index].Email) > 0 {
err = s.UpdateClientStat(oldClients[index].Email, &clients[index]) err = s.UpdateClientStat(oldClients[index].Email, &clients[0])
if err != nil { if err != nil {
return err return err
} }
} else { } else {
s.AddClientStat(inbound.Id, &clients[index]) s.AddClientStat(data.Id, &clients[0])
} }
} else { } else {
err = s.DelClientStat(db, oldClients[index].Email) err = s.DelClientStat(db, oldClients[index].Email)