diff --git a/frontend/src/generated/examples.ts b/frontend/src/generated/examples.ts index a9a9a598b..07416e8a1 100644 --- a/frontend/src/generated/examples.ts +++ b/frontend/src/generated/examples.ts @@ -50,6 +50,7 @@ export const EXAMPLES: Record = { "subEnable": false, "subEnableRouting": false, "subEncrypt": false, + "subHideSettings": false, "subJsonEnable": false, "subJsonFinalMask": "", "subJsonMux": "", @@ -147,6 +148,7 @@ export const EXAMPLES: Record = { "subEnable": false, "subEnableRouting": false, "subEncrypt": false, + "subHideSettings": false, "subJsonEnable": false, "subJsonFinalMask": "", "subJsonMux": "", diff --git a/frontend/src/generated/schemas.ts b/frontend/src/generated/schemas.ts index 185288e8b..beaa93cce 100644 --- a/frontend/src/generated/schemas.ts +++ b/frontend/src/generated/schemas.ts @@ -196,6 +196,10 @@ export const SCHEMAS: Record = { "description": "Encrypt subscription responses", "type": "boolean" }, + "subHideSettings": { + "description": "Hide server settings in happ subscription (Only for Happ)", + "type": "boolean" + }, "subJsonEnable": { "description": "Enable JSON subscription endpoint", "type": "boolean" @@ -413,6 +417,7 @@ export const SCHEMAS: Record = { "subEnable", "subEnableRouting", "subEncrypt", + "subHideSettings", "subJsonEnable", "subJsonFinalMask", "subJsonMux", @@ -672,6 +677,10 @@ export const SCHEMAS: Record = { "description": "Encrypt subscription responses", "type": "boolean" }, + "subHideSettings": { + "description": "Hide server settings in happ subscription (Only for Happ)", + "type": "boolean" + }, "subJsonEnable": { "description": "Enable JSON subscription endpoint", "type": "boolean" @@ -896,6 +905,7 @@ export const SCHEMAS: Record = { "subEnable", "subEnableRouting", "subEncrypt", + "subHideSettings", "subJsonEnable", "subJsonFinalMask", "subJsonMux", diff --git a/frontend/src/generated/types.ts b/frontend/src/generated/types.ts index a3a3bf32e..98cfc53df 100644 --- a/frontend/src/generated/types.ts +++ b/frontend/src/generated/types.ts @@ -56,6 +56,7 @@ export interface AllSetting { subEnable: boolean; subEnableRouting: boolean; subEncrypt: boolean; + subHideSettings: boolean; subJsonEnable: boolean; subJsonFinalMask: string; subJsonMux: string; @@ -154,6 +155,7 @@ export interface AllSettingView { subEnable: boolean; subEnableRouting: boolean; subEncrypt: boolean; + subHideSettings: boolean; subJsonEnable: boolean; subJsonFinalMask: string; subJsonMux: string; diff --git a/frontend/src/generated/zod.ts b/frontend/src/generated/zod.ts index 88989e77a..9499970c5 100644 --- a/frontend/src/generated/zod.ts +++ b/frontend/src/generated/zod.ts @@ -68,6 +68,7 @@ export const AllSettingSchema = z.object({ subEnable: z.boolean(), subEnableRouting: z.boolean(), subEncrypt: z.boolean(), + subHideSettings: z.boolean(), subJsonEnable: z.boolean(), subJsonFinalMask: z.string(), subJsonMux: z.string(), @@ -167,6 +168,7 @@ export const AllSettingViewSchema = z.object({ subEnable: z.boolean(), subEnableRouting: z.boolean(), subEncrypt: z.boolean(), + subHideSettings: z.boolean(), subJsonEnable: z.boolean(), subJsonFinalMask: z.string(), subJsonMux: z.string(), diff --git a/frontend/src/models/setting.ts b/frontend/src/models/setting.ts index fd22da6b3..e76e08d67 100644 --- a/frontend/src/models/setting.ts +++ b/frontend/src/models/setting.ts @@ -57,6 +57,7 @@ export class AllSetting { subJsonRules = ''; subJsonFinalMask = ''; subThemeDir = ''; + subHideSettings = false; timeLocation = 'Local'; diff --git a/frontend/src/pages/settings/SubscriptionGeneralTab.tsx b/frontend/src/pages/settings/SubscriptionGeneralTab.tsx index cb5a76f78..926d3c8e3 100644 --- a/frontend/src/pages/settings/SubscriptionGeneralTab.tsx +++ b/frontend/src/pages/settings/SubscriptionGeneralTab.tsx @@ -153,6 +153,9 @@ export default function SubscriptionGeneralTab({ allSetting, updateSetting }: Su updateSetting({ subRoutingRules: e.target.value })} /> + + updateSetting({ subHideSettings: v })} /> + ), }, diff --git a/frontend/src/schemas/setting.ts b/frontend/src/schemas/setting.ts index 708ebe1a2..abf30c41d 100644 --- a/frontend/src/schemas/setting.ts +++ b/frontend/src/schemas/setting.ts @@ -61,6 +61,7 @@ export const AllSettingSchema = z.object({ subJsonMux: z.string().optional(), subJsonRules: z.string().optional(), subJsonFinalMask: z.string().optional(), + subHideSettings: z.boolean().optional(), timeLocation: z.string().optional(), ldapEnable: z.boolean().optional(), ldapHost: z.string().optional(), diff --git a/internal/sub/controller.go b/internal/sub/controller.go index 0c684c567..5412f42a6 100644 --- a/internal/sub/controller.go +++ b/internal/sub/controller.go @@ -48,6 +48,7 @@ type SUBController struct { subAnnounce string subEnableRouting bool subRoutingRules string + subHideSettings bool subPath string subJsonPath string subClashPath string @@ -87,6 +88,7 @@ func NewSUBController( subAnnounce string, subEnableRouting bool, subRoutingRules string, + subHideSettings bool, ) *SUBController { sub := NewSubService(remarkTemplate) a := &SUBController{ @@ -96,6 +98,7 @@ func NewSUBController( subAnnounce: subAnnounce, subEnableRouting: subEnableRouting, subRoutingRules: subRoutingRules, + subHideSettings: subHideSettings, subPath: subPath, subJsonPath: jsonPath, subClashPath: clashPath, @@ -178,7 +181,7 @@ func (a *SUBController) subs(c *gin.Context) { if profileUrl == "" { profileUrl = fmt.Sprintf("%s://%s%s", scheme, hostWithPort, c.Request.RequestURI) } - a.ApplyCommonHeaders(c, header, a.updateInterval, a.subTitle, a.subSupportUrl, profileUrl, a.subAnnounce, a.subEnableRouting, a.subRoutingRules) + a.ApplyCommonHeaders(c, header, a.updateInterval, a.subTitle, a.subSupportUrl, profileUrl, a.subAnnounce, a.subEnableRouting, a.subRoutingRules, a.subHideSettings) if a.subEncrypt { c.String(200, base64.StdEncoding.EncodeToString([]byte(result.String()))) @@ -357,7 +360,7 @@ func (a *SUBController) subJsons(c *gin.Context) { if profileUrl == "" { profileUrl = fmt.Sprintf("%s://%s%s", scheme, hostWithPort, c.Request.RequestURI) } - a.ApplyCommonHeaders(c, header, a.updateInterval, a.subTitle, a.subSupportUrl, profileUrl, a.subAnnounce, a.subEnableRouting, a.subRoutingRules) + a.ApplyCommonHeaders(c, header, a.updateInterval, a.subTitle, a.subSupportUrl, profileUrl, a.subAnnounce, a.subEnableRouting, a.subRoutingRules, a.subHideSettings) c.String(200, jsonSub) } @@ -374,7 +377,7 @@ func (a *SUBController) subClashs(c *gin.Context) { if profileUrl == "" { profileUrl = fmt.Sprintf("%s://%s%s", scheme, hostWithPort, c.Request.RequestURI) } - a.ApplyCommonHeaders(c, header, a.updateInterval, a.subTitle, a.subSupportUrl, profileUrl, a.subAnnounce, a.subEnableRouting, a.subRoutingRules) + a.ApplyCommonHeaders(c, header, a.updateInterval, a.subTitle, a.subSupportUrl, profileUrl, a.subAnnounce, a.subEnableRouting, a.subRoutingRules, a.subHideSettings) if a.subTitle != "" { // Clash clients commonly use Content-Disposition to choose the imported profile name. c.Writer.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename*=UTF-8''%s`, url.PathEscape(a.subTitle))) @@ -394,6 +397,7 @@ func (a *SUBController) ApplyCommonHeaders( profileAnnounce string, profileEnableRouting bool, profileRoutingRules string, + profileHideSettings bool, ) { c.Writer.Header().Set("Subscription-Userinfo", header) c.Writer.Header().Set("Profile-Update-Interval", updateInterval) @@ -417,4 +421,7 @@ func (a *SUBController) ApplyCommonHeaders( if profileRoutingRules != "" { c.Writer.Header().Set("Routing", profileRoutingRules) } + if profileHideSettings { + c.Writer.Header().Set("Hide-Settings", "1") + } } diff --git a/internal/sub/sub.go b/internal/sub/sub.go index d2d08cb42..af34c5a75 100644 --- a/internal/sub/sub.go +++ b/internal/sub/sub.go @@ -170,6 +170,11 @@ func (s *Server) initRouter() (*gin.Engine, error) { SubRoutingRules = "" } + SubHideSettings, err := s.settingService.GetSubHideSettings() + if err != nil { + SubHideSettings = false + } + // set per-request localizer from headers/cookies engine.Use(locale.LocalizerMiddleware()) @@ -227,7 +232,7 @@ func (s *Server) initRouter() (*gin.Engine, error) { s.sub = NewSUBController( g, LinksPath, JsonPath, ClashPath, subJsonEnable, subClashEnable, Encrypt, RemarkTemplate, SubUpdates, SubJsonMux, SubJsonRules, SubJsonFinalMask, SubClashEnableRouting, SubClashRules, SubTitle, SubSupportUrl, - SubProfileUrl, SubAnnounce, SubEnableRouting, SubRoutingRules) + SubProfileUrl, SubAnnounce, SubEnableRouting, SubRoutingRules, SubHideSettings) return engine, nil } diff --git a/internal/web/entity/entity.go b/internal/web/entity/entity.go index ea53254ee..d651c06c9 100644 --- a/internal/web/entity/entity.go +++ b/internal/web/entity/entity.go @@ -98,6 +98,7 @@ type AllSetting struct { SubJsonRules string `json:"subJsonRules" form:"subJsonRules"` SubJsonFinalMask string `json:"subJsonFinalMask" form:"subJsonFinalMask"` // JSON subscription global finalmask (tcp/udp masks + quicParams) SubThemeDir string `json:"subThemeDir" form:"subThemeDir"` // Absolute path to a folder containing a custom subscription page template + SubHideSettings bool `json:"subHideSettings" form:"subHideSettings"` // Hide server settings in happ subscription (Only for Happ) // LDAP settings LdapEnable bool `json:"ldapEnable" form:"ldapEnable"` diff --git a/internal/web/service/setting.go b/internal/web/service/setting.go index 9e082a750..7a5cd411b 100644 --- a/internal/web/service/setting.go +++ b/internal/web/service/setting.go @@ -74,6 +74,7 @@ var defaultValueMap = map[string]string{ "subAnnounce": "", "subEnableRouting": "false", "subRoutingRules": "", + "subHideSettings": "false", "subListen": "", "subPort": "2096", "subPath": "/sub/", @@ -692,6 +693,10 @@ func (s *SettingService) GetSubRoutingRules() (string, error) { return s.getString("subRoutingRules") } +func (s *SettingService) GetSubHideSettings() (bool, error) { + return s.getBool("subHideSettings") +} + func (s *SettingService) GetSubListen() (string, error) { return s.getString("subListen") } diff --git a/internal/web/translation/ar-EG.json b/internal/web/translation/ar-EG.json index 3b2b7fbf3..65d6fcc97 100644 --- a/internal/web/translation/ar-EG.json +++ b/internal/web/translation/ar-EG.json @@ -1090,6 +1090,8 @@ "subEnableRoutingDesc": "إعداد عام لتمكين التوجيه (Routing) في عميل VPN. (فقط لـ Happ)", "subRoutingRules": "قواعد التوجيه", "subRoutingRulesDesc": "قواعد التوجيه العامة لعميل VPN. (فقط لـ Happ)", + "subHideSettings": "إخفاء إعدادات الخادم", + "subHideSettingsDesc": "إخفاء إمكانية عرض وتعديل إعدادات الخادم في عميل VPN. (فقط لـ Happ)", "subClashEnableRouting": "تفعيل التوجيه", "subClashEnableRoutingDesc": "تضمين قواعد توجيه Clash/Mihomo العامة في اشتراكات YAML المُنشأة.", "subClashRoutingRules": "قواعد التوجيه العامة", diff --git a/internal/web/translation/en-US.json b/internal/web/translation/en-US.json index 7933066a8..25fe6886d 100644 --- a/internal/web/translation/en-US.json +++ b/internal/web/translation/en-US.json @@ -1200,6 +1200,8 @@ "subEnableRoutingDesc": "Global setting to enable routing in the VPN client. (Only for Happ)", "subRoutingRules": "Routing rules", "subRoutingRulesDesc": "Global routing rules for the VPN client. (Only for Happ)", + "subHideSettings": "Hide server settings", + "subHideSettingsDesc": "Hide the ability to view and edit server configurations in the VPN client. (Only for Happ)", "subClashEnableRouting": "Enable routing", "subClashEnableRoutingDesc": "Include global Clash/Mihomo routing rules in generated YAML subscriptions.", "subClashRoutingRules": "Global routing rules", diff --git a/internal/web/translation/es-ES.json b/internal/web/translation/es-ES.json index 581b6e6d2..ab3b3b434 100644 --- a/internal/web/translation/es-ES.json +++ b/internal/web/translation/es-ES.json @@ -1090,6 +1090,8 @@ "subEnableRoutingDesc": "Configuración global para habilitar el enrutamiento en el cliente VPN. (Solo para Happ)", "subRoutingRules": "Reglas de enrutamiento", "subRoutingRulesDesc": "Reglas de enrutamiento globales para el cliente VPN. (Solo para Happ)", + "subHideSettings": "Ocultar configuración del servidor", + "subHideSettingsDesc": "Ocultar la posibilidad de ver y editar las configuraciones del servidor en el cliente VPN. (Solo para Happ)", "subClashEnableRouting": "Habilitar enrutamiento", "subClashEnableRoutingDesc": "Incluir reglas globales de enrutamiento Clash/Mihomo en las suscripciones YAML generadas.", "subClashRoutingRules": "Reglas globales de enrutamiento", diff --git a/internal/web/translation/fa-IR.json b/internal/web/translation/fa-IR.json index 24c0c5536..892841e23 100644 --- a/internal/web/translation/fa-IR.json +++ b/internal/web/translation/fa-IR.json @@ -1092,6 +1092,8 @@ "subEnableRoutingDesc": "تنظیمات سراسری برای فعال‌سازی مسیریابی در کلاینت VPN. (فقط برای Happ)", "subRoutingRules": "قوانین مسیریابی", "subRoutingRulesDesc": "قوانین مسیریابی سراسری برای کلاینت VPN. (فقط برای Happ)", + "subHideSettings": "پنهان کردن تنظیمات سرور", + "subHideSettingsDesc": "پنهان کردن توانایی مشاهده و ویرایش پیکربندی سرور در کلاینت VPN. (فقط برای Happ)", "subClashEnableRouting": "فعال‌سازی مسیریابی", "subClashEnableRoutingDesc": "قوانین مسیریابی سراسری Clash/Mihomo را در اشتراک‌های YAML تولیدشده وارد کن.", "subClashRoutingRules": "قوانین مسیریابی سراسری", diff --git a/internal/web/translation/id-ID.json b/internal/web/translation/id-ID.json index 9624e98a3..9796988c6 100644 --- a/internal/web/translation/id-ID.json +++ b/internal/web/translation/id-ID.json @@ -1090,6 +1090,8 @@ "subEnableRoutingDesc": "Pengaturan global untuk mengaktifkan perutean (routing) di klien VPN. (Hanya untuk Happ)", "subRoutingRules": "Aturan routing", "subRoutingRulesDesc": "Aturan routing global untuk klien VPN. (Hanya untuk Happ)", + "subHideSettings": "Sembunyikan pengaturan server", + "subHideSettingsDesc": "Menyembunyikan kemampuan untuk melihat dan mengedit konfigurasi server di klien VPN. (Hanya untuk Happ)", "subClashEnableRouting": "Aktifkan routing", "subClashEnableRoutingDesc": "Sertakan aturan routing global Clash/Mihomo dalam langganan YAML yang dibuat.", "subClashRoutingRules": "Aturan routing global", diff --git a/internal/web/translation/ja-JP.json b/internal/web/translation/ja-JP.json index 2dcbe57fa..ef7e24136 100644 --- a/internal/web/translation/ja-JP.json +++ b/internal/web/translation/ja-JP.json @@ -1090,6 +1090,8 @@ "subEnableRoutingDesc": "VPNクライアントでルーティングを有効にするためのグローバル設定。(Happのみ)", "subRoutingRules": "ルーティングルール", "subRoutingRulesDesc": "VPNクライアントのグローバルルーティングルール。(Happのみ)", + "subHideSettings": "サーバー設定を非表示", + "subHideSettingsDesc": "VPNクライアントでサーバー設定の表示・編集機能を非表示にします。(Happのみ)", "subClashEnableRouting": "ルーティングを有効化", "subClashEnableRoutingDesc": "生成されたYAMLサブスクリプションにClash/Mihomoのグローバルルーティングルールを含めます。", "subClashRoutingRules": "グローバルルーティングルール", diff --git a/internal/web/translation/pt-BR.json b/internal/web/translation/pt-BR.json index 94c569148..f29c33bf1 100644 --- a/internal/web/translation/pt-BR.json +++ b/internal/web/translation/pt-BR.json @@ -1090,6 +1090,8 @@ "subEnableRoutingDesc": "Configuração global para habilitar o roteamento no cliente VPN. (Apenas para Happ)", "subRoutingRules": "Regras de roteamento", "subRoutingRulesDesc": "Regras de roteamento globais para o cliente VPN. (Apenas para Happ)", + "subHideSettings": "Ocultar configurações do servidor", + "subHideSettingsDesc": "Ocultar a capacidade de visualizar e editar as configurações do servidor no cliente VPN. (Apenas para Happ)", "subClashEnableRouting": "Ativar roteamento", "subClashEnableRoutingDesc": "Incluir regras globais de roteamento Clash/Mihomo nas assinaturas YAML geradas.", "subClashRoutingRules": "Regras globais de roteamento", diff --git a/internal/web/translation/ru-RU.json b/internal/web/translation/ru-RU.json index d03b44a5c..33222e595 100644 --- a/internal/web/translation/ru-RU.json +++ b/internal/web/translation/ru-RU.json @@ -1090,6 +1090,8 @@ "subEnableRoutingDesc": "Глобальная настройка для включения маршрутизации в VPN-клиенте. (Только для Happ)", "subRoutingRules": "Правила маршрутизации", "subRoutingRulesDesc": "Глобальные правила маршрутизации для VPN-клиента. (Только для Happ)", + "subHideSettings": "Скрыть настройки сервера", + "subHideSettingsDesc": "Скрыть возможность просмотра и редактирования конфигурации сервера в VPN-клиенте. (Только для Happ)", "subClashEnableRouting": "Включить маршрутизацию", "subClashEnableRoutingDesc": "Добавлять глобальные правила маршрутизации Clash/Mihomo в сгенерированные YAML-подписки.", "subClashRoutingRules": "Глобальные правила маршрутизации", diff --git a/internal/web/translation/tr-TR.json b/internal/web/translation/tr-TR.json index 427a45344..1db33c635 100644 --- a/internal/web/translation/tr-TR.json +++ b/internal/web/translation/tr-TR.json @@ -1090,6 +1090,8 @@ "subEnableRoutingDesc": "VPN istemcisinde yönlendirmeyi etkinleştirmek için genel ayar. (Yalnızca Happ için)", "subRoutingRules": "Yönlendirme kuralları", "subRoutingRulesDesc": "VPN istemcisi için genel yönlendirme kuralları. (Yalnızca Happ için)", + "subHideSettings": "Sunucu ayarlarını gizle", + "subHideSettingsDesc": "VPN istemcisinde sunucu yapılandırmalarını görüntüleme ve düzenleme özelliğini gizleyin. (Yalnızca Happ için)", "subClashEnableRouting": "Yönlendirmeyi Etkinleştir", "subClashEnableRoutingDesc": "Oluşturulan YAML aboneliklerine genel Clash/Mihomo yönlendirme kurallarını ekler.", "subClashRoutingRules": "Genel Yönlendirme Kuralları", diff --git a/internal/web/translation/uk-UA.json b/internal/web/translation/uk-UA.json index 50dc0bf96..5a7295560 100644 --- a/internal/web/translation/uk-UA.json +++ b/internal/web/translation/uk-UA.json @@ -1090,6 +1090,8 @@ "subEnableRoutingDesc": "Глобальне налаштування для увімкнення маршрутизації у VPN-клієнті. (Тільки для Happ)", "subRoutingRules": "Правила маршрутизації", "subRoutingRulesDesc": "Глобальні правила маршрутизації для VPN-клієнта. (Тільки для Happ)", + "subHideSettings": "Приховати налаштування сервера", + "subHideSettingsDesc": "Приховати можливість перегляду та редагування конфігурації сервера у VPN-клієнті. (Тільки для Happ)", "subClashEnableRouting": "Увімкнути маршрутизацію", "subClashEnableRoutingDesc": "Додавати глобальні правила маршрутизації Clash/Mihomo до згенерованих YAML-підписок.", "subClashRoutingRules": "Глобальні правила маршрутизації", diff --git a/internal/web/translation/vi-VN.json b/internal/web/translation/vi-VN.json index 0c3b70c44..20dd24644 100644 --- a/internal/web/translation/vi-VN.json +++ b/internal/web/translation/vi-VN.json @@ -1090,6 +1090,8 @@ "subEnableRoutingDesc": "Cài đặt toàn cục để bật định tuyến trong ứng dụng khách VPN. (Chỉ dành cho Happ)", "subRoutingRules": "Quy tắc định tuyến", "subRoutingRulesDesc": "Quy tắc định tuyến toàn cầu cho client VPN. (Chỉ dành cho Happ)", + "subHideSettings": "Ẩn cài đặt máy chủ", + "subHideSettingsDesc": "Ẩn khả năng xem và chỉnh sửa cấu hình máy chủ trong ứng dụng khách VPN. (Chỉ dành cho Happ)", "subClashEnableRouting": "Bật định tuyến", "subClashEnableRoutingDesc": "Bao gồm quy tắc định tuyến Clash/Mihomo toàn cầu trong các đăng ký YAML được tạo.", "subClashRoutingRules": "Quy tắc định tuyến toàn cầu", diff --git a/internal/web/translation/zh-CN.json b/internal/web/translation/zh-CN.json index c16c19734..4513348c8 100644 --- a/internal/web/translation/zh-CN.json +++ b/internal/web/translation/zh-CN.json @@ -1090,6 +1090,8 @@ "subEnableRoutingDesc": "在 VPN 客户端中启用路由的全局设置。(僅限 Happ)", "subRoutingRules": "路由規則", "subRoutingRulesDesc": "VPN 用戶端的全域路由規則。(僅限 Happ)", + "subHideSettings": "隐藏服务器设置", + "subHideSettingsDesc": "在 VPN 客户端中隐藏查看和编辑服务器配置的功能。(僅限 Happ)", "subClashEnableRouting": "启用路由", "subClashEnableRoutingDesc": "在生成的 YAML 订阅中包含 Clash/Mihomo 全局路由规则。", "subClashRoutingRules": "全局路由规则", diff --git a/internal/web/translation/zh-TW.json b/internal/web/translation/zh-TW.json index b93870da2..5e1db3700 100644 --- a/internal/web/translation/zh-TW.json +++ b/internal/web/translation/zh-TW.json @@ -1090,6 +1090,8 @@ "subEnableRoutingDesc": "在 VPN 用戶端中啟用路由的全域設定。(僅限 Happ)", "subRoutingRules": "路由規則", "subRoutingRulesDesc": "VPN 用戶端的全域路由規則。(僅限 Happ)", + "subHideSettings": "隱藏伺服器設定", + "subHideSettingsDesc": "在 VPN 用戶端中隱藏查看和編輯伺服器配置的功能。(僅限 Happ)", "subClashEnableRouting": "啟用路由", "subClashEnableRoutingDesc": "在產生的 YAML 訂閱中包含 Clash/Mihomo 全域路由規則。", "subClashRoutingRules": "全域路由規則",