From 1ae1c16132055ebaadf4dd1693ee374e5b249073 Mon Sep 17 00:00:00 2001 From: Peter_Liu Date: Wed, 18 Feb 2026 16:52:18 +0800 Subject: [PATCH] feat: Add NordVPN NordLynx (WireGuard) integration with dedicated UI and backend services. --- web/controller/xray_setting.go | 28 +++ web/html/modals/nord_modal.html | 255 ++++++++++++++++++++++++++ web/html/settings/xray/basics.html | 19 ++ web/html/settings/xray/outbounds.html | 2 + web/html/xray.html | 22 +++ web/service/nord.go | 104 +++++++++++ web/service/setting.go | 9 + web/translation/translate.en_US.toml | 10 + web/translation/translate.fa_IR.toml | 10 + web/translation/translate.zh_CN.toml | 13 +- 10 files changed, 469 insertions(+), 3 deletions(-) create mode 100644 web/html/modals/nord_modal.html create mode 100644 web/service/nord.go diff --git a/web/controller/xray_setting.go b/web/controller/xray_setting.go index 5b7a0e26..0c382fb9 100644 --- a/web/controller/xray_setting.go +++ b/web/controller/xray_setting.go @@ -17,6 +17,7 @@ type XraySettingController struct { OutboundService service.OutboundService XrayService service.XrayService WarpService service.WarpService + NordService service.NordService } // NewXraySettingController creates a new XraySettingController and initializes its routes. @@ -35,6 +36,7 @@ func (a *XraySettingController) initRouter(g *gin.RouterGroup) { g.POST("/", a.getXraySetting) g.POST("/warp/:action", a.warp) + g.POST("/nord/:action", a.nord) g.POST("/update", a.updateSetting) g.POST("/resetOutboundsTraffic", a.resetOutboundsTraffic) g.POST("/testOutbound", a.testOutbound) @@ -123,6 +125,32 @@ func (a *XraySettingController) warp(c *gin.Context) { jsonObj(c, resp, err) } +// nord handles NordVPN-related operations based on the action parameter. +func (a *XraySettingController) nord(c *gin.Context) { + action := c.Param("action") + var resp string + var err error + switch action { + case "countries": + resp, err = a.NordService.GetCountries() + case "servers": + countryId := c.PostForm("countryId") + resp, err = a.NordService.GetServers(countryId) + case "reg": + token := c.PostForm("token") + resp, err = a.NordService.GetCredentials(token) + case "setKey": + key := c.PostForm("key") + resp, err = a.NordService.SetKey(key) + case "data": + resp, err = a.NordService.GetNordData() + case "del": + err = a.NordService.DelNordData() + } + + jsonObj(c, resp, err) +} + // getOutboundsTraffic retrieves the traffic statistics for outbounds. func (a *XraySettingController) getOutboundsTraffic(c *gin.Context) { outboundsTraffic, err := a.OutboundService.GetOutboundsTraffic() diff --git a/web/html/modals/nord_modal.html b/web/html/modals/nord_modal.html new file mode 100644 index 00000000..814712db --- /dev/null +++ b/web/html/modals/nord_modal.html @@ -0,0 +1,255 @@ +{{define "modals/nordModal"}} + + + + + + +{{end}} diff --git a/web/html/settings/xray/basics.html b/web/html/settings/xray/basics.html index 9a31038a..c637e30a 100644 --- a/web/html/settings/xray/basics.html +++ b/web/html/settings/xray/basics.html @@ -313,6 +313,25 @@ + + + + diff --git a/web/html/settings/xray/outbounds.html b/web/html/settings/xray/outbounds.html index 3995760f..232fe55e 100644 --- a/web/html/settings/xray/outbounds.html +++ b/web/html/settings/xray/outbounds.html @@ -9,6 +9,8 @@ WARP + NordVPN diff --git a/web/html/xray.html b/web/html/xray.html index ebe31f48..ab78fad6 100644 --- a/web/html/xray.html +++ b/web/html/xray.html @@ -166,6 +166,7 @@ {{template "modals/dnsPresetsModal"}} {{template "modals/fakednsModal"}} {{template "modals/warpModal"}} +{{template "modals/nordModal"}}