mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-02-04 12:40:07 +00:00
init jwt
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@@ -11,7 +10,6 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/hashicorp/go-uuid"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"golang.org/x/sync/singleflight"
|
||||
|
||||
@@ -68,7 +66,7 @@ func (p *commonPage) issueViewPassword(c *gin.Context) {
|
||||
err := c.ShouldBind(&vpf)
|
||||
var hash []byte
|
||||
if err == nil && vpf.Password != singleton.Conf.Site.ViewPassword {
|
||||
err = errors.New(singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "WrongAccessPassword"}))
|
||||
// err = errors.New(singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "WrongAccessPassword"}))
|
||||
}
|
||||
if err == nil {
|
||||
hash, err = bcrypt.GenerateFromPassword([]byte(vpf.Password), bcrypt.DefaultCost)
|
||||
@@ -76,9 +74,9 @@ func (p *commonPage) issueViewPassword(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusOK,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "AnErrorEccurred",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "AnErrorEccurred",
|
||||
// }),
|
||||
Msg: err.Error(),
|
||||
}, true)
|
||||
c.Abort()
|
||||
@@ -107,7 +105,7 @@ func (p *commonPage) service(c *gin.Context) {
|
||||
}, nil
|
||||
})
|
||||
c.HTML(http.StatusOK, mygin.GetPreferredTheme(c, "/service"), mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesStatus"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesStatus"}),
|
||||
"Services": res.([]interface{})[0],
|
||||
"CycleTransferStats": res.([]interface{})[1],
|
||||
}))
|
||||
@@ -255,9 +253,9 @@ func (cp *commonPage) home(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusInternalServerError,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "SystemError",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "SystemError",
|
||||
// }),
|
||||
Msg: "服务器状态获取失败",
|
||||
Link: "/",
|
||||
Btn: "返回首页",
|
||||
@@ -284,9 +282,9 @@ func (cp *commonPage) ws(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusInternalServerError,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "NetworkError",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "NetworkError",
|
||||
// }),
|
||||
Msg: "Websocket协议切换失败",
|
||||
Link: "/",
|
||||
Btn: "返回首页",
|
||||
@@ -332,9 +330,9 @@ func (cp *commonPage) terminal(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusInternalServerError,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "NetworkError",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "NetworkError",
|
||||
// }),
|
||||
Msg: "Websocket协议切换失败",
|
||||
Link: "/",
|
||||
Btn: "返回首页",
|
||||
@@ -394,9 +392,9 @@ func (cp *commonPage) createTerminal(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusInternalServerError,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "SystemError",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "SystemError",
|
||||
// }),
|
||||
Msg: "生成会话ID失败",
|
||||
Link: "/server",
|
||||
Btn: "返回重试",
|
||||
@@ -462,9 +460,9 @@ func (cp *commonPage) fm(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusInternalServerError,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "NetworkError",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "NetworkError",
|
||||
// }),
|
||||
Msg: "Websocket协议切换失败",
|
||||
Link: "/",
|
||||
Btn: "返回首页",
|
||||
@@ -508,9 +506,9 @@ func (cp *commonPage) createFM(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusInternalServerError,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "SystemError",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "SystemError",
|
||||
// }),
|
||||
Msg: "生成会话ID失败",
|
||||
Link: "/server",
|
||||
Btn: "返回重试",
|
||||
|
||||
@@ -2,20 +2,14 @@ package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/bytefmt"
|
||||
jwt "github.com/appleboy/gin-jwt/v2"
|
||||
"github.com/gin-contrib/pprof"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/hashicorp/go-uuid"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
swaggerfiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
|
||||
@@ -24,11 +18,29 @@ import (
|
||||
"github.com/naiba/nezha/pkg/mygin"
|
||||
"github.com/naiba/nezha/pkg/utils"
|
||||
"github.com/naiba/nezha/proto"
|
||||
"github.com/naiba/nezha/resource"
|
||||
"github.com/naiba/nezha/service/rpc"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
)
|
||||
|
||||
// @title Swagger Example API
|
||||
// @version 1.0
|
||||
// @description This is a sample server celler server.
|
||||
// @termsOfService http://swagger.io/terms/
|
||||
|
||||
// @contact.name API Support
|
||||
// @contact.url http://www.swagger.io/support
|
||||
// @contact.email support@swagger.io
|
||||
|
||||
// @license.name Apache 2.0
|
||||
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
// @host localhost:8080
|
||||
// @BasePath /api/v1
|
||||
|
||||
// @securityDefinitions.basic BasicAuth
|
||||
|
||||
// @externalDocs.description OpenAPI
|
||||
// @externalDocs.url https://swagger.io/resources/open-api/
|
||||
func ServeWeb(port uint) *http.Server {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
r := gin.Default()
|
||||
@@ -39,16 +51,7 @@ func ServeWeb(port uint) *http.Server {
|
||||
}
|
||||
r.Use(natGateway)
|
||||
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
|
||||
tmpl := template.New("").Funcs(funcMap)
|
||||
var err error
|
||||
tmpl, err = tmpl.ParseFS(resource.TemplateFS, "template/**/*.html")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
tmpl = loadThirdPartyTemplates(tmpl)
|
||||
r.SetHTMLTemplate(tmpl)
|
||||
r.Use(mygin.RecordPath)
|
||||
r.StaticFS("/static", http.FS(resource.StaticFS))
|
||||
routers(r)
|
||||
page404 := func(c *gin.Context) {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
@@ -71,6 +74,19 @@ func ServeWeb(port uint) *http.Server {
|
||||
}
|
||||
|
||||
func routers(r *gin.Engine) {
|
||||
authMiddleware, err := jwt.New(initParams())
|
||||
if err != nil {
|
||||
log.Fatal("JWT Error:" + err.Error())
|
||||
}
|
||||
|
||||
// register middleware
|
||||
r.Use(handlerMiddleWare(authMiddleware))
|
||||
|
||||
r.POST("/login", authMiddleware.LoginHandler)
|
||||
|
||||
auth := r.Group("/auth", authMiddleware.MiddlewareFunc())
|
||||
auth.GET("/refresh_token", authMiddleware.RefreshHandler)
|
||||
|
||||
// 通用页面
|
||||
cp := commonPage{r: r}
|
||||
cp.serve()
|
||||
@@ -88,206 +104,6 @@ func routers(r *gin.Engine) {
|
||||
}
|
||||
}
|
||||
|
||||
func loadThirdPartyTemplates(tmpl *template.Template) *template.Template {
|
||||
ret := tmpl
|
||||
themes, err := os.ReadDir("resource/template")
|
||||
if err != nil {
|
||||
log.Printf("NEZHA>> Error reading themes folder: %v", err)
|
||||
return ret
|
||||
}
|
||||
for _, theme := range themes {
|
||||
if !theme.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
themeDir := theme.Name()
|
||||
if themeDir == "theme-custom" {
|
||||
// for backward compatibility
|
||||
// note: will remove this in future versions
|
||||
ret = loadTemplates(ret, themeDir)
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(themeDir, "dashboard-") {
|
||||
// load dashboard templates, ignore desc file
|
||||
ret = loadTemplates(ret, themeDir)
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(themeDir, "theme-") {
|
||||
log.Printf("NEZHA>> Invalid theme name: %s", themeDir)
|
||||
continue
|
||||
}
|
||||
|
||||
descPath := filepath.Join("resource", "template", themeDir, "theme.json")
|
||||
desc, err := os.ReadFile(filepath.Clean(descPath))
|
||||
if err != nil {
|
||||
log.Printf("NEZHA>> Error opening %s config: %v", themeDir, err)
|
||||
continue
|
||||
}
|
||||
|
||||
themeName, err := utils.GjsonGet(desc, "name")
|
||||
if err != nil {
|
||||
log.Printf("NEZHA>> Error opening %s config: not a valid description file", theme.Name())
|
||||
continue
|
||||
}
|
||||
|
||||
// load templates
|
||||
ret = loadTemplates(ret, themeDir)
|
||||
|
||||
themeKey := strings.TrimPrefix(themeDir, "theme-")
|
||||
model.Themes[themeKey] = themeName.String()
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func loadTemplates(tmpl *template.Template, themeDir string) *template.Template {
|
||||
// load templates
|
||||
templatePath := filepath.Join("resource", "template", themeDir, "*.html")
|
||||
t, err := tmpl.ParseGlob(templatePath)
|
||||
if err != nil {
|
||||
log.Printf("NEZHA>> Error parsing templates %s: %v", themeDir, err)
|
||||
return tmpl
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
var funcMap = template.FuncMap{
|
||||
"tr": func(id string, dataAndCount ...interface{}) string {
|
||||
conf := i18n.LocalizeConfig{
|
||||
MessageID: id,
|
||||
}
|
||||
if len(dataAndCount) > 0 {
|
||||
conf.TemplateData = dataAndCount[0]
|
||||
}
|
||||
if len(dataAndCount) > 1 {
|
||||
conf.PluralCount = dataAndCount[1]
|
||||
}
|
||||
return singleton.Localizer.MustLocalize(&conf)
|
||||
},
|
||||
"toValMap": func(val interface{}) map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"Value": val,
|
||||
}
|
||||
},
|
||||
"tf": func(t time.Time) string {
|
||||
return t.In(singleton.Loc).Format("01/02/2006 15:04:05")
|
||||
},
|
||||
"len": func(slice []interface{}) string {
|
||||
return strconv.Itoa(len(slice))
|
||||
},
|
||||
"safe": func(s string) template.HTML {
|
||||
return template.HTML(s) // #nosec
|
||||
},
|
||||
"tag": func(s string) template.HTML {
|
||||
return template.HTML(`<` + s + `>`) // #nosec
|
||||
},
|
||||
"stf": func(s uint64) string {
|
||||
return time.Unix(int64(s), 0).In(singleton.Loc).Format("01/02/2006 15:04")
|
||||
},
|
||||
"sf": func(duration uint64) string {
|
||||
return time.Duration(time.Duration(duration) * time.Second).String()
|
||||
},
|
||||
"sft": func(future time.Time) string {
|
||||
return time.Until(future).Round(time.Second).String()
|
||||
},
|
||||
"bf": func(b uint64) string {
|
||||
return bytefmt.ByteSize(b)
|
||||
},
|
||||
"ts": func(s string) string {
|
||||
return strings.TrimSpace(s)
|
||||
},
|
||||
"float32f": func(f float32) string {
|
||||
return fmt.Sprintf("%.3f", f)
|
||||
},
|
||||
"divU64": func(a, b uint64) float32 {
|
||||
if b == 0 {
|
||||
if a > 0 {
|
||||
return 100
|
||||
}
|
||||
return 0
|
||||
}
|
||||
if a == 0 {
|
||||
// 这是从未在线的情况
|
||||
return 0.00001 / float32(b) * 100
|
||||
}
|
||||
return float32(a) / float32(b) * 100
|
||||
},
|
||||
"div": func(a, b int) float32 {
|
||||
if b == 0 {
|
||||
if a > 0 {
|
||||
return 100
|
||||
}
|
||||
return 0
|
||||
}
|
||||
if a == 0 {
|
||||
// 这是从未在线的情况
|
||||
return 0.00001 / float32(b) * 100
|
||||
}
|
||||
return float32(a) / float32(b) * 100
|
||||
},
|
||||
"addU64": func(a, b uint64) uint64 {
|
||||
return a + b
|
||||
},
|
||||
"add": func(a, b int) int {
|
||||
return a + b
|
||||
},
|
||||
"TransLeftPercent": func(a, b float64) (n float64) {
|
||||
n, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", (100-(a/b)*100)), 64)
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
return
|
||||
},
|
||||
"TransLeft": func(a, b uint64) string {
|
||||
if a < b {
|
||||
return "0B"
|
||||
}
|
||||
return bytefmt.ByteSize(a - b)
|
||||
},
|
||||
"TransClassName": func(a float64) string {
|
||||
if a == 0 {
|
||||
return "offline"
|
||||
}
|
||||
if a > 50 {
|
||||
return "fine"
|
||||
}
|
||||
if a > 20 {
|
||||
return "warning"
|
||||
}
|
||||
if a > 0 {
|
||||
return "error"
|
||||
}
|
||||
return "offline"
|
||||
},
|
||||
"UintToFloat": func(a uint64) (n float64) {
|
||||
n, _ = strconv.ParseFloat((strconv.FormatUint(a, 10)), 64)
|
||||
return
|
||||
},
|
||||
"dayBefore": func(i int) string {
|
||||
year, month, day := time.Now().Date()
|
||||
today := time.Date(year, month, day, 0, 0, 0, 0, singleton.Loc)
|
||||
return today.AddDate(0, 0, i-29).Format("01/02")
|
||||
},
|
||||
"className": func(percent float32) string {
|
||||
if percent == 0 {
|
||||
return ""
|
||||
}
|
||||
if percent > 95 {
|
||||
return "good"
|
||||
}
|
||||
if percent > 80 {
|
||||
return "warning"
|
||||
}
|
||||
return "danger"
|
||||
},
|
||||
"statusName": func(val float32) string {
|
||||
return singleton.StatusCodeToString(singleton.GetStatusCode(val))
|
||||
},
|
||||
}
|
||||
|
||||
func natGateway(c *gin.Context) {
|
||||
natConfig := singleton.GetNATConfigByDomain(c.Request.Host)
|
||||
if natConfig == nil {
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
|
||||
"github.com/naiba/nezha/model"
|
||||
"github.com/naiba/nezha/pkg/mygin"
|
||||
@@ -56,7 +55,7 @@ func (gp *guestPage) login(c *gin.Context) {
|
||||
RegistrationLink = singleton.Conf.Oauth2.OidcRegisterURL
|
||||
}
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/login", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
|
||||
"LoginType": LoginType,
|
||||
"RegistrationLink": RegistrationLink,
|
||||
}))
|
||||
|
||||
96
cmd/dashboard/controller/jwt.go
Normal file
96
cmd/dashboard/controller/jwt.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
jwt "github.com/appleboy/gin-jwt/v2"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/naiba/nezha/model"
|
||||
)
|
||||
|
||||
func initParams() *jwt.GinJWTMiddleware {
|
||||
return &jwt.GinJWTMiddleware{
|
||||
Realm: "test zone",
|
||||
Key: []byte("secret key"),
|
||||
Timeout: time.Hour,
|
||||
MaxRefresh: time.Hour,
|
||||
IdentityKey: model.CtxKeyAuthorizedUser,
|
||||
PayloadFunc: payloadFunc(),
|
||||
|
||||
IdentityHandler: identityHandler(),
|
||||
Authenticator: authenticator(),
|
||||
Authorizator: authorizator(),
|
||||
Unauthorized: unauthorized(),
|
||||
TokenLookup: "header: Authorization, query: token, cookie: jwt",
|
||||
TokenHeadName: "Bearer",
|
||||
TimeFunc: time.Now,
|
||||
}
|
||||
}
|
||||
|
||||
func handlerMiddleWare(authMiddleware *jwt.GinJWTMiddleware) gin.HandlerFunc {
|
||||
return func(context *gin.Context) {
|
||||
errInit := authMiddleware.MiddlewareInit()
|
||||
if errInit != nil {
|
||||
log.Fatal("authMiddleware.MiddlewareInit() Error:" + errInit.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func payloadFunc() func(data interface{}) jwt.MapClaims {
|
||||
return func(data interface{}) jwt.MapClaims {
|
||||
if v, ok := data.(*model.User); ok {
|
||||
return jwt.MapClaims{
|
||||
model.CtxKeyAuthorizedUser: v.Username,
|
||||
}
|
||||
}
|
||||
return jwt.MapClaims{}
|
||||
}
|
||||
}
|
||||
|
||||
func identityHandler() func(c *gin.Context) interface{} {
|
||||
return func(c *gin.Context) interface{} {
|
||||
claims := jwt.ExtractClaims(c)
|
||||
return &model.User{
|
||||
Username: claims[model.CtxKeyAuthorizedUser].(string),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func authenticator() func(c *gin.Context) (interface{}, error) {
|
||||
return func(c *gin.Context) (interface{}, error) {
|
||||
var loginVals model.LoginRequest
|
||||
if err := c.ShouldBind(&loginVals); err != nil {
|
||||
return "", jwt.ErrMissingLoginValues
|
||||
}
|
||||
userID := loginVals.Username
|
||||
password := loginVals.Password
|
||||
|
||||
if (userID == "admin" && password == "admin") || (userID == "test" && password == "test") {
|
||||
return &model.User{
|
||||
Username: userID,
|
||||
}, nil
|
||||
}
|
||||
return nil, jwt.ErrFailedAuthentication
|
||||
}
|
||||
}
|
||||
|
||||
func authorizator() func(data interface{}, c *gin.Context) bool {
|
||||
return func(data interface{}, c *gin.Context) bool {
|
||||
if v, ok := data.(*model.User); ok && v.Username == "admin" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func unauthorized() func(c *gin.Context, code int, message string) {
|
||||
return func(c *gin.Context, code int, message string) {
|
||||
c.JSON(code, model.CommonResponse{
|
||||
Success: false,
|
||||
Error: model.CommonError{
|
||||
Code: model.ApiErrorUnauthorized,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
"github.com/naiba/nezha/pkg/mygin"
|
||||
"github.com/naiba/nezha/pkg/utils"
|
||||
"github.com/naiba/nezha/proto"
|
||||
"github.com/naiba/nezha/resource"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
)
|
||||
|
||||
@@ -1050,22 +1049,6 @@ func (ma *memberAPI) updateSetting(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if !utils.IsFileExists("resource/template/theme-"+sf.Theme+"/home.html") && !resource.IsTemplateFileExist("template/theme-"+sf.Theme+"/home.html") {
|
||||
c.JSON(http.StatusOK, model.Response{
|
||||
Code: http.StatusBadRequest,
|
||||
Message: fmt.Sprintf("前台主题文件异常:%s", sf.Theme),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if !utils.IsFileExists("resource/template/dashboard-"+sf.DashboardTheme+"/setting.html") && !resource.IsTemplateFileExist("template/dashboard-"+sf.DashboardTheme+"/setting.html") {
|
||||
c.JSON(http.StatusOK, model.Response{
|
||||
Code: http.StatusBadRequest,
|
||||
Message: fmt.Sprintf("后台主题文件异常:%s", sf.DashboardTheme),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
singleton.Conf.Language = sf.Language
|
||||
singleton.Conf.EnableIPChangeNotification = sf.EnableIPChangeNotification == "on"
|
||||
singleton.Conf.EnablePlainIPInNotification = sf.EnablePlainIPInNotification == "on"
|
||||
@@ -1093,8 +1076,6 @@ func (ma *memberAPI) updateSetting(c *gin.Context) {
|
||||
})
|
||||
return
|
||||
}
|
||||
// 更新系统语言
|
||||
singleton.InitLocalizer()
|
||||
// 更新DNS服务器
|
||||
singleton.OnNameserverUpdate()
|
||||
c.JSON(http.StatusOK, model.Response{
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/naiba/nezha/model"
|
||||
"github.com/naiba/nezha/pkg/mygin"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
)
|
||||
|
||||
type memberPage struct {
|
||||
@@ -19,9 +18,9 @@ func (mp *memberPage) serve() {
|
||||
mr.Use(mygin.Authorize(mygin.AuthorizeOption{
|
||||
MemberOnly: true,
|
||||
IsPage: true,
|
||||
Msg: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "YouAreNotAuthorized"}),
|
||||
Btn: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
|
||||
Redirect: "/login",
|
||||
// Msg: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "YouAreNotAuthorized"}),
|
||||
// Btn: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
|
||||
Redirect: "/login",
|
||||
}))
|
||||
mr.GET("/server", mp.server)
|
||||
mr.GET("/monitor", mp.monitor)
|
||||
@@ -37,7 +36,7 @@ func (mp *memberPage) api(c *gin.Context) {
|
||||
singleton.ApiLock.RLock()
|
||||
defer singleton.ApiLock.RUnlock()
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/api", mygin.CommonEnvironment(c, gin.H{
|
||||
"title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ApiManagement"}),
|
||||
// "title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ApiManagement"}),
|
||||
"Tokens": singleton.ApiTokenList,
|
||||
}))
|
||||
}
|
||||
@@ -46,14 +45,14 @@ func (mp *memberPage) server(c *gin.Context) {
|
||||
singleton.SortedServerLock.RLock()
|
||||
defer singleton.SortedServerLock.RUnlock()
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/server", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServersManagement"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServersManagement"}),
|
||||
"Servers": singleton.SortedServerList,
|
||||
}))
|
||||
}
|
||||
|
||||
func (mp *memberPage) monitor(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/monitor", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesManagement"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesManagement"}),
|
||||
"Monitors": singleton.ServiceSentinelShared.Monitors(),
|
||||
}))
|
||||
}
|
||||
@@ -62,7 +61,7 @@ func (mp *memberPage) cron(c *gin.Context) {
|
||||
var crons []model.Cron
|
||||
singleton.DB.Find(&crons)
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/cron", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ScheduledTasks"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ScheduledTasks"}),
|
||||
"Crons": crons,
|
||||
}))
|
||||
}
|
||||
@@ -73,7 +72,7 @@ func (mp *memberPage) notification(c *gin.Context) {
|
||||
var ar []model.AlertRule
|
||||
singleton.DB.Find(&ar)
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/notification", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Notification"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Notification"}),
|
||||
"Notifications": nf,
|
||||
"AlertRules": ar,
|
||||
}))
|
||||
@@ -83,7 +82,7 @@ func (mp *memberPage) ddns(c *gin.Context) {
|
||||
var data []model.DDNSProfile
|
||||
singleton.DB.Find(&data)
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/ddns", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "DDNS"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "DDNS"}),
|
||||
"DDNS": data,
|
||||
"ProviderMap": model.ProviderMap,
|
||||
"ProviderList": model.ProviderList,
|
||||
@@ -94,14 +93,14 @@ func (mp *memberPage) nat(c *gin.Context) {
|
||||
var data []model.NAT
|
||||
singleton.DB.Find(&data)
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/nat", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "NAT"}),
|
||||
"NAT": data,
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "NAT"}),
|
||||
"NAT": data,
|
||||
}))
|
||||
}
|
||||
|
||||
func (mp *memberPage) setting(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/setting", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Settings"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Settings"}),
|
||||
"Languages": model.Languages,
|
||||
"DashboardThemes": model.DashboardThemes,
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user