From a5f6e074cd21862f0c08ff814e8326ab0e67ab00 Mon Sep 17 00:00:00 2001 From: Hossin Asaadi Date: Wed, 9 Nov 2022 11:02:20 -0500 Subject: [PATCH 1/6] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f0d4216..d129cf83 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ xray panel supporting multi-protocol, **Multi-lang (English,Chinese)**, **IP Res | ------------- |:-------------:| | Multi-lang | :heavy_check_mark: | | IP Restriction | :heavy_check_mark: | -| Inbound Multi User | :clock1: | +| Inbound Multi User | :heavy_check_mark: | **If you think this project is helpful to you, you may wish to give a** :star2: From 5939a38e31136be30bc94bb44f1bc96f4a1b91fb Mon Sep 17 00:00:00 2001 From: Saeed Darestany <39810501+saeeddarestany@users.noreply.github.com> Date: Sat, 12 Nov 2022 18:50:51 +0330 Subject: [PATCH 2/6] The language of the Telegram bot has been changed to English (#36) Co-authored-by: Saeed Darestany <39810501+isaeeed@users.noreply.github.com> --- web/job/stats_notify_job.go | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/web/job/stats_notify_job.go b/web/job/stats_notify_job.go index 1090d61b..5dba7be8 100644 --- a/web/job/stats_notify_job.go +++ b/web/job/stats_notify_job.go @@ -4,13 +4,10 @@ import ( "fmt" "net" "os" - "time" - "x-ui/logger" "x-ui/util/common" "x-ui/web/service" - tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" ) @@ -69,7 +66,7 @@ func (j *StatsNotifyJob) Run() { fmt.Println("get hostname error:", err) return } - info = fmt.Sprintf("主机名称:%s\r\n", name) + info = fmt.Sprintf("Hostname:%s\r\n", name) //get ip address var ip string netInterfaces, err := net.Interfaces() @@ -95,7 +92,7 @@ func (j *StatsNotifyJob) Run() { } } } - info += fmt.Sprintf("IP地址:%s\r\n \r\n", ip) + info += fmt.Sprintf("IP:%s\r\n \r\n", ip) //get traffic inbouds, err := j.inboundService.GetAllInbounds() @@ -106,11 +103,11 @@ func (j *StatsNotifyJob) Run() { //NOTE:If there no any sessions here,need to notify here //TODO:分节点推送,自动转化格式 for _, inbound := range inbouds { - info += fmt.Sprintf("节点名称:%s\r\n端口:%d\r\n上行流量↑:%s\r\n下行流量↓:%s\r\n总流量:%s\r\n", inbound.Remark, inbound.Port, common.FormatTraffic(inbound.Up), common.FormatTraffic(inbound.Down), common.FormatTraffic((inbound.Up + inbound.Down))) + info += fmt.Sprintf("Node name:%s\r\nPort:%d\r\nUpload↑:%s\r\nDownload↓:%s\r\nTotal:%s\r\n", inbound.Remark, inbound.Port, common.FormatTraffic(inbound.Up), common.FormatTraffic(inbound.Down), common.FormatTraffic((inbound.Up + inbound.Down))) if inbound.ExpiryTime == 0 { - info += fmt.Sprintf("到期时间:无限期\r\n \r\n") + info += fmt.Sprintf("Expire date:unlimited\r\n \r\n") } else { - info += fmt.Sprintf("到期时间:%s\r\n \r\n", time.Unix((inbound.ExpiryTime/1000), 0).Format("2006-01-02 15:04:05")) + info += fmt.Sprintf("Expire date:%s\r\n \r\n", time.Unix((inbound.ExpiryTime/1000), 0).Format("2006-01-02 15:04:05")) } } j.SendMsgToTgbot(info) @@ -129,12 +126,12 @@ func (j *StatsNotifyJob) UserLoginNotify(username string, ip string, time string return } if status == LoginSuccess { - msg = fmt.Sprintf("面板登录成功提醒\r\n主机名称:%s\r\n", name) + msg = fmt.Sprintf("Successfully logged-in to the panel\r\nHostname:%s\r\n", name) } else if status == LoginFail { - msg = fmt.Sprintf("面板登录失败提醒\r\n主机名称:%s\r\n", name) + msg = fmt.Sprintf("Login to the panel was unsuccessful\r\nHostname:%s\r\n", name) } - msg += fmt.Sprintf("时间:%s\r\n", time) - msg += fmt.Sprintf("用户:%s\r\n", username) + msg += fmt.Sprintf("Time:%s\r\n", time) + msg += fmt.Sprintf("Username:%s\r\n", username) msg += fmt.Sprintf("IP:%s\r\n", ip) j.SendMsgToTgbot(msg) } From c52bdc79c06b65f5bbffe7e60149788510ca8767 Mon Sep 17 00:00:00 2001 From: Hossin Asaadi Date: Sun, 13 Nov 2022 02:54:55 -0500 Subject: [PATCH 3/6] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d129cf83..6fbea2a7 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ xray panel supporting multi-protocol, **Multi-lang (English,Chinese)**, **IP Res **If you think this project is helpful to you, you may wish to give a** :star2: +**Feel Free for Donation :** :heart: + +TRC20: TDam6uh8ctLJuz8Y3rRk4t5pLikQvtpvJE + +ETH: 0x256ddA590c35638fA4B3a25Ec4544Db087ceE826 + # Features - System Status Monitoring @@ -38,7 +44,7 @@ xray panel supporting multi-protocol, **Multi-lang (English,Chinese)**, **IP Res ``` - change access log path as you want -2 - add **IP limit and Email** for inbound(vmess & vless) +2 - add **IP limit and Unique Email** for inbound(vmess & vless) # Install & Upgrade From 2ef3ef36aaf1957e332aebc38df13b0a7c9f5981 Mon Sep 17 00:00:00 2001 From: Hossin Asaadi Date: Tue, 15 Nov 2022 05:56:58 -0500 Subject: [PATCH 4/6] set vless limitIp min to 0 --- web/html/xui/form/protocol/vless.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/html/xui/form/protocol/vless.html b/web/html/xui/form/protocol/vless.html index 0b6e6a5f..246bf1e7 100644 --- a/web/html/xui/form/protocol/vless.html +++ b/web/html/xui/form/protocol/vless.html @@ -16,7 +16,7 @@ - + @@ -118,4 +118,4 @@ -{{end}} \ No newline at end of file +{{end}} From 796a2bd7941a766d07cc68beeac2ec2b664583f0 Mon Sep 17 00:00:00 2001 From: Hossin Asaadi Date: Tue, 15 Nov 2022 05:57:31 -0500 Subject: [PATCH 5/6] set vmess limitIP min to 0 --- web/html/xui/form/protocol/vmess.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/html/xui/form/protocol/vmess.html b/web/html/xui/form/protocol/vmess.html index 4d7fa4f4..5eb53432 100644 --- a/web/html/xui/form/protocol/vmess.html +++ b/web/html/xui/form/protocol/vmess.html @@ -16,7 +16,7 @@ - + @@ -85,4 +85,4 @@ -{{end}} \ No newline at end of file +{{end}} From 845409f1b443600acdedff5f39e494a12fdad339 Mon Sep 17 00:00:00 2001 From: Hossin Asaadi Date: Tue, 15 Nov 2022 15:39:43 +0330 Subject: [PATCH 6/6] add API (#51) --- web/controller/api.go | 48 ++++++++++++++++++++++++++++ web/controller/inbound.go | 23 ++++++++++--- web/job/stats_notify_job.go | 2 +- web/service/inbound.go | 19 +++++------ web/translation/translate.en_US.toml | 2 +- web/web.go | 2 ++ 6 files changed, 80 insertions(+), 16 deletions(-) create mode 100644 web/controller/api.go diff --git a/web/controller/api.go b/web/controller/api.go new file mode 100644 index 00000000..84ac9c20 --- /dev/null +++ b/web/controller/api.go @@ -0,0 +1,48 @@ +package controller + +import ( + "github.com/gin-gonic/gin" +) +type APIController struct { + BaseController + + inboundController *InboundController + settingController *SettingController +} + +func NewAPIController(g *gin.RouterGroup) *APIController { + a := &APIController{} + a.initRouter(g) + return a +} + +func (a *APIController) initRouter(g *gin.RouterGroup) { + g = g.Group("/xui/API/inbounds") + g.Use(a.checkLogin) + + g.GET("/", a.inbounds) + g.GET("/get/:id", a.inbound) + g.POST("/add", a.addInbound) + g.POST("/del/:id", a.delInbound) + g.POST("/update/:id", a.updateInbound) + + + a.inboundController = NewInboundController(g) +} + + +func (a *APIController) inbounds(c *gin.Context) { + a.inboundController.getInbounds(c) +} +func (a *APIController) inbound(c *gin.Context) { + a.inboundController.getInbound(c) +} +func (a *APIController) addInbound(c *gin.Context) { + a.inboundController.addInbound(c) +} +func (a *APIController) delInbound(c *gin.Context) { + a.inboundController.delInbound(c) +} +func (a *APIController) updateInbound(c *gin.Context) { + a.inboundController.updateInbound(c) +} diff --git a/web/controller/inbound.go b/web/controller/inbound.go index a3867598..a23aed07 100644 --- a/web/controller/inbound.go +++ b/web/controller/inbound.go @@ -59,6 +59,19 @@ func (a *InboundController) getInbounds(c *gin.Context) { } jsonObj(c, inbounds, nil) } +func (a *InboundController) getInbound(c *gin.Context) { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + jsonMsg(c, I18n(c , "get"), err) + return + } + inbound, err := a.inboundService.GetInbound(id) + if err != nil { + jsonMsg(c, I18n(c , "pages.inbounds.toasts.obtain"), err) + return + } + jsonObj(c, inbound, nil) +} func (a *InboundController) addInbound(c *gin.Context) { inbound := &model.Inbound{} @@ -71,8 +84,8 @@ func (a *InboundController) addInbound(c *gin.Context) { inbound.UserId = user.Id inbound.Enable = true inbound.Tag = fmt.Sprintf("inbound-%v", inbound.Port) - err = a.inboundService.AddInbound(inbound) - jsonMsg(c, I18n(c , "pages.inbounds.addTo"), err) + inbound, err = a.inboundService.AddInbound(inbound) + jsonMsgObj(c, I18n(c , "pages.inbounds.addTo"), inbound, err) if err == nil { a.xrayService.SetToNeedRestart() } @@ -85,7 +98,7 @@ func (a *InboundController) delInbound(c *gin.Context) { return } err = a.inboundService.DelInbound(id) - jsonMsg(c, I18n(c , "delete"), err) + jsonMsgObj(c, I18n(c , "delete"), id, err) if err == nil { a.xrayService.SetToNeedRestart() } @@ -105,8 +118,8 @@ func (a *InboundController) updateInbound(c *gin.Context) { jsonMsg(c, I18n(c , "pages.inbounds.revise"), err) return } - err = a.inboundService.UpdateInbound(inbound) - jsonMsg(c, I18n(c , "pages.inbounds.revise"), err) + inbound, err = a.inboundService.UpdateInbound(inbound) + jsonMsgObj(c, I18n(c , "pages.inbounds.revise"), inbound, err) if err == nil { a.xrayService.SetToNeedRestart() } diff --git a/web/job/stats_notify_job.go b/web/job/stats_notify_job.go index 5dba7be8..a3e15a9e 100644 --- a/web/job/stats_notify_job.go +++ b/web/job/stats_notify_job.go @@ -32,7 +32,7 @@ func NewStatsNotifyJob() *StatsNotifyJob { func (j *StatsNotifyJob) SendMsgToTgbot(msg string) { //Telegram bot basic info tgBottoken, err := j.settingService.GetTgBotToken() - if err != nil { + if err != nil || tgBottoken == "" { logger.Warning("sendMsgToTgbot failed,GetTgBotToken fail:", err) return } diff --git a/web/service/inbound.go b/web/service/inbound.go index d440cbce..d5a685a8 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -48,16 +48,17 @@ func (s *InboundService) checkPortExist(port int, ignoreId int) (bool, error) { return count > 0, nil } -func (s *InboundService) AddInbound(inbound *model.Inbound) error { +func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound,error) { exist, err := s.checkPortExist(inbound.Port, 0) if err != nil { - return err + return inbound, err } if exist { - return common.NewError("端口已存在:", inbound.Port) + return inbound, common.NewError("端口已存在:", inbound.Port) } db := database.GetDB() - return db.Save(inbound).Error + + return inbound, db.Save(inbound).Error } func (s *InboundService) AddInbounds(inbounds []*model.Inbound) error { @@ -107,18 +108,18 @@ func (s *InboundService) GetInbound(id int) (*model.Inbound, error) { return inbound, nil } -func (s *InboundService) UpdateInbound(inbound *model.Inbound) error { +func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound, error) { exist, err := s.checkPortExist(inbound.Port, inbound.Id) if err != nil { - return err + return inbound, err } if exist { - return common.NewError("端口已存在:", inbound.Port) + return inbound, common.NewError("端口已存在:", inbound.Port) } oldInbound, err := s.GetInbound(inbound.Id) if err != nil { - return err + return inbound, err } oldInbound.Up = inbound.Up oldInbound.Down = inbound.Down @@ -135,7 +136,7 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) error { oldInbound.Tag = fmt.Sprintf("inbound-%v", inbound.Port) db := database.GetDB() - return db.Save(oldInbound).Error + return inbound, db.Save(oldInbound).Error } func (s *InboundService) AddTraffic(traffics []*xray.Traffic) (err error) { diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml index bb441e29..6fe9356a 100644 --- a/web/translation/translate.en_US.toml +++ b/web/translation/translate.en_US.toml @@ -38,7 +38,7 @@ "monitor" = "Listen IP" "certificate" = "certificat" "fail" = "fail" -"success" = "success" +"success" = " success" "getVersion" = "get version" "install" = "install" diff --git a/web/web.go b/web/web.go index fd6f4907..0b37a81a 100644 --- a/web/web.go +++ b/web/web.go @@ -84,6 +84,7 @@ type Server struct { index *controller.IndexController server *controller.ServerController xui *controller.XUIController + api *controller.APIController xrayService service.XrayService settingService service.SettingService @@ -206,6 +207,7 @@ func (s *Server) initRouter() (*gin.Engine, error) { s.index = controller.NewIndexController(g) s.server = controller.NewServerController(g) s.xui = controller.NewXUIController(g) + s.api = controller.NewAPIController(g) return engine, nil }