From a8878bc1dcd10f704cb807e9f3ee0ef5b842e5ce Mon Sep 17 00:00:00 2001 From: Alireza Ahmadi Date: Sun, 26 Nov 2023 18:37:45 +0100 Subject: [PATCH] [sub] url support for reverse proxy #607 --- web/assets/js/model/setting.js | 1 + web/controller/setting.go | 42 ++--------------- web/entity/entity.go | 8 ++++ web/html/common/qrcode_modal.html | 3 +- web/html/xui/inbound_info_modal.html | 3 +- web/html/xui/inbounds.html | 10 +--- web/html/xui/settings.html | 1 + web/service/setting.go | 63 ++++++++++++++++++++++++++ web/translation/translate.en_US.toml | 2 + web/translation/translate.fa_IR.toml | 2 + web/translation/translate.ru_RU.toml | 2 + web/translation/translate.zh_Hans.toml | 2 + 12 files changed, 89 insertions(+), 50 deletions(-) diff --git a/web/assets/js/model/setting.js b/web/assets/js/model/setting.js index f299e90b..06f66f81 100644 --- a/web/assets/js/model/setting.js +++ b/web/assets/js/model/setting.js @@ -29,6 +29,7 @@ class AllSetting { this.subUpdates = 0; this.subEncrypt = true; this.subShowInfo = false; + this.subURI = ''; this.timeLocation = "Asia/Tehran"; diff --git a/web/controller/setting.go b/web/controller/setting.go index c03910e2..020c8dc5 100644 --- a/web/controller/setting.go +++ b/web/controller/setting.go @@ -50,45 +50,11 @@ func (a *SettingController) getAllSetting(c *gin.Context) { } func (a *SettingController) getDefaultSettings(c *gin.Context) { - type settingFunc func() (interface{}, error) - - settings := map[string]settingFunc{ - "expireDiff": func() (interface{}, error) { return a.settingService.GetExpireDiff() }, - "trafficDiff": func() (interface{}, error) { return a.settingService.GetTrafficDiff() }, - "defaultCert": func() (interface{}, error) { return a.settingService.GetCertFile() }, - "defaultKey": func() (interface{}, error) { return a.settingService.GetKeyFile() }, - "tgBotEnable": func() (interface{}, error) { return a.settingService.GetTgbotenabled() }, - "subEnable": func() (interface{}, error) { return a.settingService.GetSubEnable() }, - "subPort": func() (interface{}, error) { return a.settingService.GetSubPort() }, - "subPath": func() (interface{}, error) { return a.settingService.GetSubPath() }, - "subDomain": func() (interface{}, error) { return a.settingService.GetSubDomain() }, - "subKeyFile": func() (interface{}, error) { return a.settingService.GetSubKeyFile() }, - "subCertFile": func() (interface{}, error) { return a.settingService.GetSubCertFile() }, - "subEncrypt": func() (interface{}, error) { return a.settingService.GetSubEncrypt() }, - "subShowInfo": func() (interface{}, error) { return a.settingService.GetSubShowInfo() }, - "pageSize": func() (interface{}, error) { return a.settingService.GetPageSize() }, + result, err := a.settingService.GetDefaultSettings(c.Request.Host) + if err != nil { + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err) + return } - - result := make(map[string]interface{}) - - for key, fn := range settings { - value, err := fn() - if err != nil { - jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err) - return - } - result[key] = value - } - - subTLS := false - if result["subKeyFile"] != "" || result["subCertFile"] != "" { - subTLS = true - } - result["subTLS"] = subTLS - - delete(result, "subKeyFile") - delete(result, "subCertFile") - jsonObj(c, result, nil) } diff --git a/web/entity/entity.go b/web/entity/entity.go index 50e4f8aa..9b45c1ad 100644 --- a/web/entity/entity.go +++ b/web/entity/entity.go @@ -44,6 +44,7 @@ type AllSetting struct { SubUpdates int `json:"subUpdates" form:"subUpdates"` SubEncrypt bool `json:"subEncrypt" form:"subEncrypt"` SubShowInfo bool `json:"subShowInfo" form:"subShowInfo"` + SubURI string `json:"subURI" form:"subURI"` } func (s *AllSetting) CheckValid() error { @@ -94,6 +95,13 @@ func (s *AllSetting) CheckValid() error { s.WebBasePath += "/" } + if !strings.HasPrefix(s.SubPath, "/") { + s.SubPath = "/" + s.SubPath + } + if !strings.HasSuffix(s.SubPath, "/") { + s.SubPath += "/" + } + _, err := time.LoadLocation(s.TimeLocation) if err != nil { return common.NewError("time location not exist:", s.TimeLocation) diff --git a/web/html/common/qrcode_modal.html b/web/html/common/qrcode_modal.html index 4d237edb..8c0c13d7 100644 --- a/web/html/common/qrcode_modal.html +++ b/web/html/common/qrcode_modal.html @@ -83,8 +83,7 @@ }); }, genSubLink(subID) { - const { domain: host, port, tls: isTLS, path: base } = app.subSettings; - return buildURL({ host, port, isTLS, base, path: subID+'?name='+subID }); + return app.subSettings.subURI+subID+'?name='+subID; } }, updated() { diff --git a/web/html/xui/inbound_info_modal.html b/web/html/xui/inbound_info_modal.html index 081f454e..27c90d37 100644 --- a/web/html/xui/inbound_info_modal.html +++ b/web/html/xui/inbound_info_modal.html @@ -296,8 +296,7 @@ infoModal.visible = false; }, genSubLink(subID) { - const { domain: host, port, tls: isTLS, path: base } = app.subSettings; - return buildURL({ host, port, isTLS, base, path: subID+'?name='+subID }); + return app.subSettings.subURI+subID+'?name='+subID; } }; diff --git a/web/html/xui/inbounds.html b/web/html/xui/inbounds.html index 3bbca632..7a700a34 100644 --- a/web/html/xui/inbounds.html +++ b/web/html/xui/inbounds.html @@ -544,10 +544,7 @@ refreshInterval: Number(localStorage.getItem("refreshInterval")) || 5000, subSettings: { enable : false, - port: 0, - path: '', - domain: '', - tls: false + subURI : '' }, tgBotEnable: false, showAlert: false, @@ -591,10 +588,7 @@ this.tgBotEnable = tgBotEnable; this.subSettings = { enable : subEnable, - port: subPort, - path: subPath, - domain: subDomain, - tls: subTLS + subURI: subURI }; this.pageSize = pageSize; } diff --git a/web/html/xui/settings.html b/web/html/xui/settings.html index 44d0bbdf..ce8c2f3d 100644 --- a/web/html/xui/settings.html +++ b/web/html/xui/settings.html @@ -176,6 +176,7 @@ + diff --git a/web/service/setting.go b/web/service/setting.go index fec65a28..aea8f07a 100644 --- a/web/service/setting.go +++ b/web/service/setting.go @@ -53,6 +53,7 @@ var defaultValueMap = map[string]string{ "subUpdates": "12", "subEncrypt": "true", "subShowInfo": "false", + "subURI": "", } type SettingService struct { @@ -387,6 +388,10 @@ func (s *SettingService) GetPageSize() (int, error) { return s.getInt("pageSize") } +func (s *SettingService) GetSubURI() (string, error) { + return s.getString("subURI") +} + func (s *SettingService) UpdateAllSetting(allSetting *entity.AllSetting) error { if err := allSetting.CheckValid(); err != nil { return err @@ -416,3 +421,61 @@ func (s *SettingService) GetDefaultXrayConfig() (interface{}, error) { } return jsonData, nil } + +func (s *SettingService) GetDefaultSettings(host string) (interface{}, error) { + type settingFunc func() (interface{}, error) + settings := map[string]settingFunc{ + "expireDiff": func() (interface{}, error) { return s.GetExpireDiff() }, + "trafficDiff": func() (interface{}, error) { return s.GetTrafficDiff() }, + "pageSize": func() (interface{}, error) { return s.GetPageSize() }, + "defaultCert": func() (interface{}, error) { return s.GetCertFile() }, + "defaultKey": func() (interface{}, error) { return s.GetKeyFile() }, + "tgBotEnable": func() (interface{}, error) { return s.GetTgbotenabled() }, + "subEnable": func() (interface{}, error) { return s.GetSubEnable() }, + "subURI": func() (interface{}, error) { return s.GetSubURI() }, + } + + result := make(map[string]interface{}) + + for key, fn := range settings { + value, err := fn() + if err != nil { + return "", err + } + result[key] = value + } + + if result["subEnable"].(bool) && result["subURI"].(string) == "" { + subURI := "" + subPort, _ := s.GetSubPort() + subPath, _ := s.GetSubPath() + subDomain, _ := s.GetSubDomain() + subKeyFile, _ := s.GetSubKeyFile() + subCertFile, _ := s.GetSubCertFile() + subTLS := false + if subKeyFile != "" && subCertFile != "" { + subTLS = true + } + if subDomain == "" { + subDomain = strings.Split(host, ":")[0] + } + if subTLS { + subURI = "https://" + } else { + subURI = "http://" + } + if (subPort == 443 && subTLS) || (subPort == 80 && !subTLS) { + subURI += subDomain + } else { + subURI += fmt.Sprintf("%s:%d", subDomain, subPort) + } + if subPath[0] == byte('/') { + subURI += subPath + } else { + subURI += "/" + subPath + } + result["subURI"] = subURI + } + + return result, nil +} diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml index 4ac8bb4a..f0e6619c 100644 --- a/web/translation/translate.en_US.toml +++ b/web/translation/translate.en_US.toml @@ -279,6 +279,8 @@ "subEncryptDesc" = "Encrypt the returned configs in subscription" "subShowInfo" = "Show usage info" "subShowInfoDesc" = "Show remianed traffic and date after config name" +"subURI" = "Reverse Proxy URI" +"subURIDesc" = "Change base URI of subscription URL for using on behind of proxies" [pages.settings.toasts] "modifySettings" = "Modify Settings " diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml index e2018b0d..38e13a5d 100644 --- a/web/translation/translate.fa_IR.toml +++ b/web/translation/translate.fa_IR.toml @@ -278,6 +278,8 @@ "subEncryptDesc" = "رمزگذاری کانفیگ های بازگشتی سابسکریپشن" "subShowInfo" = "نمایش اطلاعات مصرف" "subShowInfoDesc" = "ترافیک و زمان باقیمانده را در هر کانفیگ نمایش میدهد" +"subURI" = "آدرس پایه پروکسی معکوس" +"subURIDesc" = "آدرس پایه سابسکریپشن را برای استفاده در پشت پراکسی ها تغییر میدهد" [pages.settings.toasts] "modifySettings" = "ویرایش تنظیمات" diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml index 6ecb3fc5..4dd1a292 100644 --- a/web/translation/translate.ru_RU.toml +++ b/web/translation/translate.ru_RU.toml @@ -279,6 +279,8 @@ "subEncryptDesc" = "Шифрование возвращаемых конфигураций в подписке" "subShowInfo" = "Показать информацию об использовании" "subShowInfoDesc" = "Показывать восстановленный трафик и дату после имени конфигурации" +"subURI" = "URI обратного прокси" +"subURIDesc" = "Изменить базовый URI URL-адреса подписки для использования за прокси-серверами" [pages.settings.toasts] "modifySettings" = "Изменение настроек" diff --git a/web/translation/translate.zh_Hans.toml b/web/translation/translate.zh_Hans.toml index 5bf4466a..9cae8bc0 100644 --- a/web/translation/translate.zh_Hans.toml +++ b/web/translation/translate.zh_Hans.toml @@ -279,6 +279,8 @@ "subEncryptDesc" = "在订阅中加密返回的配置" "subShowInfo" = "显示使用信息" "subShowInfoDesc" = "在配置名称后显示剩余流量和日期" +"subURI" = "反向代理 URI" +"subURIDesc" = "更改订阅 URL 的基本 URI 以在代理后面使用" [pages.settings.toasts] "modifySettings" = "修改设置"