diff --git a/cmd/dashboard/controller/common_page.go b/cmd/dashboard/controller/common_page.go deleted file mode 100644 index 3de8ecc..0000000 --- a/cmd/dashboard/controller/common_page.go +++ /dev/null @@ -1,257 +0,0 @@ -package controller - -import ( - "net/http" - "strconv" - "time" - - "github.com/gin-gonic/gin" - "github.com/gorilla/websocket" - "github.com/hashicorp/go-uuid" - - "github.com/naiba/nezha/model" - "github.com/naiba/nezha/pkg/utils" - "github.com/naiba/nezha/pkg/websocketx" - "github.com/naiba/nezha/proto" - "github.com/naiba/nezha/service/rpc" - "github.com/naiba/nezha/service/singleton" -) - -type commonPage struct { - r *gin.Engine -} - -func (cp *commonPage) serve() { - cr := cp.r.Group("") - // TODO: 界面直接跳转使用该接口 - cr.GET("/network/:id", cp.network) - cr.GET("/network", cp.network) - cr.GET("/file", cp.createFM) - cr.GET("/file/:id", cp.fm) -} - -func (cp *commonPage) network(c *gin.Context) { - var ( - monitorHistory *model.ServiceHistory - servers []model.Server - serverIdsWithMonitor []uint64 - monitorInfos = []byte("{}") - id uint64 - ) - if len(singleton.SortedServerList) > 0 { - id = singleton.SortedServerList[0].ID - } - if err := singleton.DB.Model(&model.ServiceHistory{}).Select("monitor_id, server_id"). - Where("monitor_id != 0 and server_id != 0").Limit(1).First(&monitorHistory).Error; err != nil { - // mygin.ShowErrorPage(c, mygin.ErrInfo{ - // Code: http.StatusForbidden, - // Title: "请求失败", - // Msg: "请求参数有误:" + "server monitor history not found", - // Link: "/", - // Btn: "返回重试", - // }, true) - return - } else { - if monitorHistory == nil || monitorHistory.ServerID == 0 { - if len(singleton.SortedServerList) > 0 { - id = singleton.SortedServerList[0].ID - } - } else { - id = monitorHistory.ServerID - } - } - - idStr := c.Param("id") - if idStr != "" { - var err error - id, err = strconv.ParseUint(idStr, 10, 64) - if err != nil { - // mygin.ShowErrorPage(c, mygin.ErrInfo{ - // Code: http.StatusForbidden, - // Title: "请求失败", - // Msg: "请求参数有误:" + err.Error(), - // Link: "/", - // Btn: "返回重试", - // }, true) - return - } - _, ok := singleton.ServerList[id] - if !ok { - // mygin.ShowErrorPage(c, mygin.ErrInfo{ - // Code: http.StatusForbidden, - // Title: "请求失败", - // Msg: "请求参数有误:" + "server id not found", - // Link: "/", - // Btn: "返回重试", - // }, true) - return - } - } - _, isMember := c.Get(model.CtxKeyAuthorizedUser) - var isViewPasswordVerfied bool - - if err := singleton.DB.Model(&model.ServiceHistory{}). - Select("distinct(server_id)"). - Where("server_id != 0"). - Find(&serverIdsWithMonitor). - Error; err != nil { - // mygin.ShowErrorPage(c, mygin.ErrInfo{ - // Code: http.StatusForbidden, - // Title: "请求失败", - // Msg: "请求参数有误:" + "no server with monitor histories", - // Link: "/", - // Btn: "返回重试", - // }, true) - return - } - if isMember || isViewPasswordVerfied { - for _, server := range singleton.SortedServerList { - for _, id := range serverIdsWithMonitor { - if server.ID == id { - servers = append(servers, *server) - } - } - } - } else { - for _, server := range singleton.SortedServerListForGuest { - for _, id := range serverIdsWithMonitor { - if server.ID == id { - servers = append(servers, *server) - } - } - } - } - serversBytes, _ := utils.Json.Marshal(model.StreamServerData{ - Now: time.Now().Unix() * 1000, - // Servers: servers, - }) - - c.HTML(http.StatusOK, "", gin.H{ - "Servers": string(serversBytes), - "MonitorInfos": string(monitorInfos), - }) -} - -func (cp *commonPage) fm(c *gin.Context) { - streamId := c.Param("id") - if _, err := rpc.NezhaHandlerSingleton.GetStream(streamId); err != nil { - // mygin.ShowErrorPage(c, mygin.ErrInfo{ - // Code: http.StatusForbidden, - // Title: "无权访问", - // Msg: "FM会话不存在", - // Link: "/", - // Btn: "返回首页", - // }, true) - return - } - defer rpc.NezhaHandlerSingleton.CloseStream(streamId) - - wsConn, err := upgrader.Upgrade(c.Writer, c.Request, nil) - if err != nil { - // mygin.ShowErrorPage(c, mygin.ErrInfo{ - // Code: http.StatusInternalServerError, - // // Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{ - // // MessageID: "NetworkError", - // // }), - // Msg: "Websocket协议切换失败", - // Link: "/", - // Btn: "返回首页", - // }, true) - return - } - defer wsConn.Close() - conn := websocketx.NewConn(wsConn) - - go func() { - // PING 保活 - for { - if err = conn.WriteMessage(websocket.PingMessage, []byte{}); err != nil { - return - } - time.Sleep(time.Second * 10) - } - }() - - if err = rpc.NezhaHandlerSingleton.UserConnected(streamId, conn); err != nil { - return - } - - rpc.NezhaHandlerSingleton.StartStream(streamId, time.Second*10) -} - -func (cp *commonPage) createFM(c *gin.Context) { - IdString := c.Query("id") - if _, authorized := c.Get(model.CtxKeyAuthorizedUser); !authorized { - // mygin.ShowErrorPage(c, mygin.ErrInfo{ - // Code: http.StatusForbidden, - // Title: "无权访问", - // Msg: "用户未登录", - // Link: "/login", - // Btn: "去登录", - // }, true) - return - } - - streamId, err := uuid.GenerateUUID() - if err != nil { - // mygin.ShowErrorPage(c, mygin.ErrInfo{ - // Code: http.StatusInternalServerError, - // // Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{ - // // MessageID: "SystemError", - // // }), - // Msg: "生成会话ID失败", - // Link: "/server", - // Btn: "返回重试", - // }, true) - return - } - - rpc.NezhaHandlerSingleton.CreateStream(streamId) - - serverId, err := strconv.Atoi(IdString) - if err != nil { - // mygin.ShowErrorPage(c, mygin.ErrInfo{ - // Code: http.StatusForbidden, - // Title: "请求失败", - // Msg: "请求参数有误:" + err.Error(), - // Link: "/server", - // Btn: "返回重试", - // }, true) - return - } - - singleton.ServerLock.RLock() - server := singleton.ServerList[uint64(serverId)] - singleton.ServerLock.RUnlock() - if server == nil { - // mygin.ShowErrorPage(c, mygin.ErrInfo{ - // Code: http.StatusForbidden, - // Title: "请求失败", - // Msg: "服务器不存在或处于离线状态", - // Link: "/server", - // Btn: "返回重试", - // }, true) - return - } - - fmData, _ := utils.Json.Marshal(&model.TaskFM{ - StreamID: streamId, - }) - if err := server.TaskStream.Send(&proto.Task{ - Type: model.TaskTypeFM, - Data: string(fmData), - }); err != nil { - // mygin.ShowErrorPage(c, mygin.ErrInfo{ - // Code: http.StatusForbidden, - // Title: "请求失败", - // Msg: "Agent信令下发失败", - // Link: "/server", - // Btn: "返回重试", - // }, true) - return - } - - c.HTML(http.StatusOK, "dashboard-", gin.H{ - "SessionID": streamId, - }) -} diff --git a/cmd/dashboard/controller/member_api.go b/cmd/dashboard/controller/member_api.go deleted file mode 100644 index 13a7aba..0000000 --- a/cmd/dashboard/controller/member_api.go +++ /dev/null @@ -1,636 +0,0 @@ -package controller - -import ( - "bytes" - "errors" - "fmt" - "net/http" - "strconv" - "strings" - "time" - - "github.com/gin-gonic/gin" - "github.com/jinzhu/copier" - "golang.org/x/net/idna" - - "github.com/naiba/nezha/model" - "github.com/naiba/nezha/pkg/utils" - "github.com/naiba/nezha/proto" - "github.com/naiba/nezha/service/singleton" -) - -type memberAPI struct { - r gin.IRouter -} - -func (ma *memberAPI) serve() { - mr := ma.r.Group("") - // mr.Use(mygin.Authorize(mygin.AuthorizeOption{ - // MemberOnly: true, - // IsPage: false, - // Msg: "访问此接口需要登录", - // Btn: "点此登录", - // Redirect: "/login", - // })) - mr.POST("/cron", ma.addOrEditCron) - mr.GET("/cron/:id/manual", ma.manualTrigger) - mr.POST("/force-update", ma.forceUpdate) - mr.POST("/batch-update-server-group", ma.batchUpdateServerGroup) - mr.POST("/notification", ma.addOrEditNotification) - mr.POST("/ddns", ma.addOrEditDDNS) - mr.POST("/nat", ma.addOrEditNAT) - mr.POST("/alert-rule", ma.addOrEditAlertRule) - mr.POST("/setting", ma.updateSetting) - mr.DELETE("/:model/:id", ma.delete) - mr.POST("/logout", ma.logout) -} - -func (ma *memberAPI) delete(c *gin.Context) { - id, _ := strconv.ParseUint(c.Param("id"), 10, 64) - if id < 1 { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: "错误的 Server ID", - }) - return - } - - var err error - switch c.Param("model") { - - case "cron": - err = singleton.DB.Unscoped().Delete(&model.Cron{}, "id = ?", id).Error - if err == nil { - singleton.CronLock.RLock() - defer singleton.CronLock.RUnlock() - cr := singleton.Crons[id] - if cr != nil && cr.CronJobID != 0 { - singleton.Cron.Remove(cr.CronJobID) - } - delete(singleton.Crons, id) - } - } - if err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: fmt.Sprintf("数据库错误:%s", err), - }) - return - } - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusOK, - }) -} - -type cronForm struct { - ID uint64 - TaskType uint8 // 0:计划任务 1:触发任务 - Name string - Scheduler string - Command string - ServersRaw string - Cover uint8 - PushSuccessful string - NotificationTag string -} - -func (ma *memberAPI) addOrEditCron(c *gin.Context) { - var cf cronForm - var cr model.Cron - err := c.ShouldBindJSON(&cf) - if err == nil { - cr.TaskType = cf.TaskType - cr.Name = cf.Name - cr.Scheduler = cf.Scheduler - cr.Command = cf.Command - cr.ServersRaw = cf.ServersRaw - cr.PushSuccessful = cf.PushSuccessful == "on" - //cr.NotificationTag = cf.NotificationTag - cr.ID = cf.ID - cr.Cover = cf.Cover - err = utils.Json.Unmarshal([]byte(cf.ServersRaw), &cr.Servers) - } - - // 计划任务类型不得使用触发服务器执行方式 - if cr.TaskType == model.CronTypeCronTask && cr.Cover == model.CronCoverAlertTrigger { - err = errors.New("计划任务类型不得使用触发服务器执行方式") - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: fmt.Sprintf("请求错误:%s", err), - }) - return - } - - tx := singleton.DB.Begin() - if err == nil { - // 保证NotificationTag不为空 - //if cr.NotificationTag == "" { - // cr.NotificationTag = "default" - //} - if cf.ID == 0 { - err = tx.Create(&cr).Error - } else { - err = tx.Save(&cr).Error - } - } - if err == nil { - err = tx.Commit().Error - } else { - tx.Rollback() - } - if err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: fmt.Sprintf("请求错误:%s", err), - }) - return - } - - singleton.CronLock.Lock() - defer singleton.CronLock.Unlock() - crOld := singleton.Crons[cr.ID] - if crOld != nil && crOld.CronJobID != 0 { - singleton.Cron.Remove(crOld.CronJobID) - } - - delete(singleton.Crons, cr.ID) - singleton.Crons[cr.ID] = &cr - - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusOK, - }) -} - -func (ma *memberAPI) manualTrigger(c *gin.Context) { - var cr model.Cron - if err := singleton.DB.First(&cr, "id = ?", c.Param("id")).Error; err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: err.Error(), - }) - return - } - - //singleton.ManualTrigger(cr) - - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusOK, - }) -} - -type BatchUpdateServerGroupRequest struct { - Servers []uint64 - Group string -} - -func (ma *memberAPI) batchUpdateServerGroup(c *gin.Context) { - var req BatchUpdateServerGroupRequest - if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: err.Error(), - }) - return - } - - if err := singleton.DB.Model(&model.Server{}).Where("id in (?)", req.Servers).Update("tag", req.Group).Error; err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: err.Error(), - }) - return - } - - singleton.ServerLock.Lock() - - for i := 0; i < len(req.Servers); i++ { - serverId := req.Servers[i] - var s model.Server - copier.Copy(&s, singleton.ServerList[serverId]) - // s.Tag = req.Group - // // 如果修改了Ta - // oldTag := singleton.ServerList[serverId].Tag - // newTag := s.Tag - // if newTag != oldTag { - // index := -1 - // for i := 0; i < len(singleton.ServerTagToIDList[oldTag]); i++ { - // if singleton.ServerTagToIDList[oldTag][i] == s.ID { - // index = i - // break - // } - // } - // if index > -1 { - // // 删除旧 Tag-ID 绑定关系 - // singleton.ServerTagToIDList[oldTag] = append(singleton.ServerTagToIDList[oldTag][:index], singleton.ServerTagToIDList[oldTag][index+1:]...) - // if len(singleton.ServerTagToIDList[oldTag]) == 0 { - // delete(singleton.ServerTagToIDList, oldTag) - // } - // } - // // 设置新的 Tag-ID 绑定关系 - // singleton.ServerTagToIDList[newTag] = append(singleton.ServerTagToIDList[newTag], s.ID) - // } - singleton.ServerList[s.ID] = &s - } - - singleton.ServerLock.Unlock() - - singleton.ReSortServer() - - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusOK, - }) -} - -func (ma *memberAPI) forceUpdate(c *gin.Context) { - var forceUpdateServers []uint64 - if err := c.ShouldBindJSON(&forceUpdateServers); err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: err.Error(), - }) - return - } - - var executeResult bytes.Buffer - - for i := 0; i < len(forceUpdateServers); i++ { - singleton.ServerLock.RLock() - server := singleton.ServerList[forceUpdateServers[i]] - singleton.ServerLock.RUnlock() - if server != nil && server.TaskStream != nil { - if err := server.TaskStream.Send(&proto.Task{ - Type: model.TaskTypeUpgrade, - }); err != nil { - executeResult.WriteString(fmt.Sprintf("%d 下发指令失败 %+v
", forceUpdateServers[i], err)) - } else { - executeResult.WriteString(fmt.Sprintf("%d 下发指令成功
", forceUpdateServers[i])) - } - } else { - executeResult.WriteString(fmt.Sprintf("%d 离线
", forceUpdateServers[i])) - } - } - - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusOK, - Message: executeResult.String(), - }) -} - -type notificationForm struct { - ID uint64 - Name string - URL string - RequestMethod int - RequestType int - RequestHeader string - RequestBody string - VerifySSL string - SkipCheck string -} - -func (ma *memberAPI) addOrEditNotification(c *gin.Context) { - var nf notificationForm - var n model.Notification - err := c.ShouldBindJSON(&nf) - if err == nil { - n.Name = nf.Name - n.RequestMethod = nf.RequestMethod - n.RequestType = nf.RequestType - n.RequestHeader = nf.RequestHeader - n.RequestBody = nf.RequestBody - n.URL = nf.URL - //verifySSL := nf.VerifySSL == "on" - //n.VerifySSL = &verifySSL - n.ID = nf.ID - ns := model.NotificationServerBundle{ - Notification: &n, - Server: nil, - Loc: singleton.Loc, - } - // 勾选了跳过检查 - if nf.SkipCheck != "on" { - err = ns.Send("这是测试消息") - } - } - if err == nil { - if n.ID == 0 { - err = singleton.DB.Create(&n).Error - } else { - err = singleton.DB.Save(&n).Error - } - } - if err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: fmt.Sprintf("请求错误:%s", err), - }) - return - } - singleton.OnRefreshOrAddNotification(&n) - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusOK, - }) -} - -type ddnsForm struct { - ID uint64 - MaxRetries uint64 - EnableIPv4 string - EnableIPv6 string - Name string - Provider string - DomainsRaw string - AccessID string - AccessSecret string - WebhookURL string - WebhookMethod uint8 - WebhookRequestType uint8 - WebhookRequestBody string - WebhookHeaders string -} - -func (ma *memberAPI) addOrEditDDNS(c *gin.Context) { - var df ddnsForm - var p model.DDNSProfile - err := c.ShouldBindJSON(&df) - if err == nil { - if df.MaxRetries < 1 || df.MaxRetries > 10 { - err = errors.New("重试次数必须为大于 1 且不超过 10 的整数") - } - } - if err == nil { - p.Name = df.Name - p.ID = df.ID - enableIPv4 := df.EnableIPv4 == "on" - enableIPv6 := df.EnableIPv6 == "on" - p.EnableIPv4 = &enableIPv4 - p.EnableIPv6 = &enableIPv6 - p.MaxRetries = df.MaxRetries - p.Provider = df.Provider - p.DomainsRaw = df.DomainsRaw - p.Domains = strings.Split(p.DomainsRaw, ",") - p.AccessID = df.AccessID - p.AccessSecret = df.AccessSecret - p.WebhookURL = df.WebhookURL - p.WebhookMethod = df.WebhookMethod - p.WebhookRequestType = df.WebhookRequestType - p.WebhookRequestBody = df.WebhookRequestBody - p.WebhookHeaders = df.WebhookHeaders - - for n, domain := range p.Domains { - // IDN to ASCII - domainValid, domainErr := idna.Lookup.ToASCII(domain) - if domainErr != nil { - err = fmt.Errorf("域名 %s 解析错误: %v", domain, domainErr) - break - } - p.Domains[n] = domainValid - } - } - if err == nil { - if p.ID == 0 { - err = singleton.DB.Create(&p).Error - } else { - err = singleton.DB.Save(&p).Error - } - } - if err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: fmt.Sprintf("请求错误:%s", err), - }) - return - } - //singleton.OnDDNSUpdate() - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusOK, - }) -} - -type natForm struct { - ID uint64 - Name string - ServerID uint64 - Host string - Domain string -} - -func (ma *memberAPI) addOrEditNAT(c *gin.Context) { - var nf natForm - var n model.NAT - err := c.ShouldBindJSON(&nf) - if err == nil { - n.Name = nf.Name - n.ID = nf.ID - n.Domain = nf.Domain - n.Host = nf.Host - n.ServerID = nf.ServerID - } - if err == nil { - if n.ID == 0 { - err = singleton.DB.Create(&n).Error - } else { - err = singleton.DB.Save(&n).Error - } - } - if err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: fmt.Sprintf("请求错误:%s", err), - }) - return - } - //singleton.OnNATUpdate() - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusOK, - }) -} - -type alertRuleForm struct { - ID uint64 - Name string - RulesRaw string - FailTriggerTasksRaw string // 失败时触发的任务id - RecoverTriggerTasksRaw string // 恢复时触发的任务id - NotificationTag string - TriggerMode int - Enable string -} - -func (ma *memberAPI) addOrEditAlertRule(c *gin.Context) { - var arf alertRuleForm - var r model.AlertRule - err := c.ShouldBindJSON(&arf) - if err == nil { - err = utils.Json.Unmarshal([]byte(arf.RulesRaw), &r.Rules) - } - if err == nil { - if len(r.Rules) == 0 { - err = errors.New("至少定义一条规则") - } else { - for i := 0; i < len(r.Rules); i++ { - if !r.Rules[i].IsTransferDurationRule() { - if r.Rules[i].Duration < 3 { - err = errors.New("错误:Duration 至少为 3") - break - } - } else { - if r.Rules[i].CycleInterval < 1 { - err = errors.New("错误: cycle_interval 至少为 1") - break - } - if r.Rules[i].CycleStart == nil { - err = errors.New("错误: cycle_start 未设置") - break - } - if r.Rules[i].CycleStart.After(time.Now()) { - err = errors.New("错误: cycle_start 是个未来值") - break - } - } - } - } - } - if err == nil { - r.Name = arf.Name - r.RulesRaw = arf.RulesRaw - r.FailTriggerTasksRaw = arf.FailTriggerTasksRaw - r.RecoverTriggerTasksRaw = arf.RecoverTriggerTasksRaw - //r.NotificationTag = arf.NotificationTag - enable := arf.Enable == "on" - r.TriggerMode = arf.TriggerMode - r.Enable = &enable - r.ID = arf.ID - } - if err == nil { - err = utils.Json.Unmarshal([]byte(arf.FailTriggerTasksRaw), &r.FailTriggerTasks) - } - if err == nil { - err = utils.Json.Unmarshal([]byte(arf.RecoverTriggerTasksRaw), &r.RecoverTriggerTasks) - } - //保证NotificationTag不为空 - if err == nil { - //if r.NotificationTag == "" { - // r.NotificationTag = "default" - //} - if r.ID == 0 { - err = singleton.DB.Create(&r).Error - } else { - err = singleton.DB.Save(&r).Error - } - } - if err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: fmt.Sprintf("请求错误:%s", err), - }) - return - } - //singleton.OnRefreshOrAddAlert(r) - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusOK, - }) -} - -type logoutForm struct { - ID uint64 -} - -func (ma *memberAPI) logout(c *gin.Context) { - admin := c.MustGet(model.CtxKeyAuthorizedUser).(*model.User) - var lf logoutForm - if err := c.ShouldBindJSON(&lf); err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: fmt.Sprintf("请求错误:%s", err), - }) - return - } - if lf.ID != admin.ID { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: fmt.Sprintf("请求错误:%s", "用户ID不匹配"), - }) - return - } - singleton.DB.Model(admin).UpdateColumns(model.User{ - // Token: "", - // TokenExpired: time.Now(), - }) - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusOK, - }) - - // if oidcLogoutUrl := singleton.Conf.Oauth2.OidcLogoutURL; oidcLogoutUrl != "" { - // // 重定向到 OIDC 退出登录地址。不知道为什么,这里的重定向不生效 - // c.Redirect(http.StatusOK, oidcLogoutUrl) - // } -} - -type settingForm struct { - SiteName string - Language string - CustomNameservers string - IgnoredIPNotification string - IPChangeNotificationTag string // IP变更提醒的通知组 - InstallHost string - Cover uint8 - - EnableIPChangeNotification string - EnablePlainIPInNotification string -} - -func (ma *memberAPI) updateSetting(c *gin.Context) { - var sf settingForm - if err := c.ShouldBind(&sf); err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: fmt.Sprintf("请求错误:%s", err), - }) - return - } - - // if _, yes := model.Themes[sf.Theme]; !yes { - // c.JSON(http.StatusOK, model.Response{ - // Code: http.StatusBadRequest, - // Message: fmt.Sprintf("前台主题不存在:%s", sf.Theme), - // }) - // return - // } - - // if _, yes := model.DashboardThemes[sf.DashboardTheme]; !yes { - // 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" - singleton.Conf.Cover = sf.Cover - singleton.Conf.InstallHost = sf.InstallHost - singleton.Conf.IgnoredIPNotification = sf.IgnoredIPNotification - singleton.Conf.IPChangeNotificationTag = sf.IPChangeNotificationTag - singleton.Conf.SiteName = sf.SiteName - singleton.Conf.DNSServers = sf.CustomNameservers - // 保证NotificationTag不为空 - if singleton.Conf.IPChangeNotificationTag == "" { - singleton.Conf.IPChangeNotificationTag = "default" - } - if err := singleton.Conf.Save(); err != nil { - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusBadRequest, - Message: fmt.Sprintf("请求错误:%s", err), - }) - return - } - // 更新DNS服务器 - singleton.OnNameserverUpdate() - c.JSON(http.StatusOK, model.Response{ - Code: http.StatusOK, - }) - */ -} diff --git a/cmd/dashboard/controller/member_page.go b/cmd/dashboard/controller/member_page.go deleted file mode 100644 index 110a069..0000000 --- a/cmd/dashboard/controller/member_page.go +++ /dev/null @@ -1,78 +0,0 @@ -package controller - -import ( - "net/http" - - "github.com/gin-gonic/gin" - "github.com/naiba/nezha/model" - "github.com/naiba/nezha/service/singleton" -) - -type memberPage struct { - r *gin.Engine -} - -func (mp *memberPage) serve() { - mr := mp.r.Group("") - // 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", - // })) - mr.GET("/cron", mp.cron) - mr.GET("/notification", mp.notification) - mr.GET("/ddns", mp.ddns) - mr.GET("/nat", mp.nat) - mr.GET("/setting", mp.setting) -} - -func (mp *memberPage) cron(c *gin.Context) { - var crons []model.Cron - singleton.DB.Find(&crons) - c.HTML(http.StatusOK, "dashboard-", gin.H{ - // "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ScheduledTasks"}), - "Crons": crons, - }) -} - -func (mp *memberPage) notification(c *gin.Context) { - var nf []model.Notification - singleton.DB.Find(&nf) - var ar []model.AlertRule - singleton.DB.Find(&ar) - c.HTML(http.StatusOK, "dashboard-", gin.H{ - // "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Notification"}), - "Notifications": nf, - "AlertRules": ar, - }) -} - -func (mp *memberPage) ddns(c *gin.Context) { - var data []model.DDNSProfile - singleton.DB.Find(&data) - c.HTML(http.StatusOK, "dashboard-", gin.H{ - // "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "DDNS"}), - "DDNS": data, - //"ProviderMap": model.ProviderMap, - //"ProviderList": model.ProviderList, - }) -} - -func (mp *memberPage) nat(c *gin.Context) { - var data []model.NAT - singleton.DB.Find(&data) - c.HTML(http.StatusOK, "dashboard-", gin.H{ - // "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "NAT"}), - "NAT": data, - }) -} - -func (mp *memberPage) setting(c *gin.Context) { - c.HTML(http.StatusOK, "dashboard-", gin.H{ - // "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Settings"}), - //"Languages": model.Languages, - //"DashboardThemes": model.DashboardThemes, - }) -}