diff --git a/backend/app/api/v1/auth.go b/backend/app/api/v1/auth.go deleted file mode 100644 index e1959e1dc..000000000 --- a/backend/app/api/v1/auth.go +++ /dev/null @@ -1,186 +0,0 @@ -package v1 - -import ( - "encoding/base64" - - "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" - "github.com/1Panel-dev/1Panel/backend/app/dto" - "github.com/1Panel-dev/1Panel/backend/app/model" - "github.com/1Panel-dev/1Panel/backend/constant" - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/1Panel-dev/1Panel/backend/middleware" - "github.com/1Panel-dev/1Panel/backend/utils/captcha" - "github.com/1Panel-dev/1Panel/backend/utils/qqwry" - "github.com/gin-gonic/gin" -) - -type BaseApi struct{} - -// @Tags Auth -// @Summary User login -// @Description 用户登录 -// @Accept json -// @Param EntranceCode header string true "安全入口 base64 加密串" -// @Param request body dto.Login true "request" -// @Success 200 {object} dto.UserLoginInfo -// @Router /auth/login [post] -func (b *BaseApi) Login(c *gin.Context) { - var req dto.Login - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if req.AuthMethod != "jwt" && !req.IgnoreCaptcha { - if err := captcha.VerifyCode(req.CaptchaID, req.Captcha); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - } - entranceItem := c.Request.Header.Get("EntranceCode") - var entrance []byte - if len(entranceItem) != 0 { - entrance, _ = base64.StdEncoding.DecodeString(entranceItem) - } - - user, err := authService.Login(c, req, string(entrance)) - go saveLoginLogs(c, err) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, user) -} - -// @Tags Auth -// @Summary User login with mfa -// @Description 用户 mfa 登录 -// @Accept json -// @Param request body dto.MFALogin true "request" -// @Success 200 {object} dto.UserLoginInfo -// @Router /auth/mfalogin [post] -// @Header 200 {string} EntranceCode "安全入口" -func (b *BaseApi) MFALogin(c *gin.Context) { - var req dto.MFALogin - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - entranceItem := c.Request.Header.Get("EntranceCode") - var entrance []byte - if len(entranceItem) != 0 { - entrance, _ = base64.StdEncoding.DecodeString(entranceItem) - } - - user, err := authService.MFALogin(c, req, string(entrance)) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, user) -} - -// @Tags Auth -// @Summary User logout -// @Description 用户登出 -// @Success 200 -// @Security ApiKeyAuth -// @Router /auth/logout [post] -func (b *BaseApi) LogOut(c *gin.Context) { - if err := authService.LogOut(c); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, nil) -} - -// @Tags Auth -// @Summary Load captcha -// @Description 加载验证码 -// @Success 200 {object} dto.CaptchaResponse -// @Router /auth/captcha [get] -func (b *BaseApi) Captcha(c *gin.Context) { - captcha, err := captcha.CreateCaptcha() - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, captcha) -} - -// @Tags Auth -// @Summary Load safety status -// @Description 获取系统安全登录状态 -// @Success 200 -// @Router /auth/issafety [get] -func (b *BaseApi) CheckIsSafety(c *gin.Context) { - code := c.DefaultQuery("code", "") - status, err := authService.CheckIsSafety(code) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - if status == "disable" && len(code) != 0 { - helper.ErrorWithDetail(c, constant.CodeErrNotFound, constant.ErrTypeInternalServer, err) - return - } - if status == "unpass" { - if middleware.LoadErrCode("err-entrance") != 200 { - helper.ErrResponse(c, middleware.LoadErrCode("err-entrance")) - return - } - helper.ErrorWithDetail(c, constant.CodeErrEntrance, constant.ErrTypeInternalServer, nil) - return - } - helper.SuccessWithOutData(c) -} - -func (b *BaseApi) GetResponsePage(c *gin.Context) { - pageCode, err := authService.GetResponsePage() - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, pageCode) -} - -// @Tags Auth -// @Summary Check System isDemo -// @Description 判断是否为demo环境 -// @Success 200 -// @Router /auth/demo [get] -func (b *BaseApi) CheckIsDemo(c *gin.Context) { - helper.SuccessWithData(c, global.CONF.System.IsDemo) -} - -// @Tags Auth -// @Summary Load System Language -// @Description 获取系统语言设置 -// @Success 200 -// @Router /auth/language [get] -func (b *BaseApi) GetLanguage(c *gin.Context) { - settingInfo, err := settingService.GetSettingInfo() - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, settingInfo.Language) -} - -func saveLoginLogs(c *gin.Context, err error) { - var logs model.LoginLog - if err != nil { - logs.Status = constant.StatusFailed - logs.Message = err.Error() - } else { - logs.Status = constant.StatusSuccess - } - logs.IP = c.ClientIP() - qqWry, err := qqwry.NewQQwry() - if err != nil { - global.LOG.Errorf("load qqwry datas failed: %s", err) - } - res := qqWry.Find(logs.IP) - logs.Agent = c.GetHeader("User-Agent") - logs.Address = res.Area - _ = logService.CreateLoginLog(logs) -} diff --git a/backend/app/api/v1/entry.go b/backend/app/api/v1/entry.go index f93b92061..dfec388d8 100644 --- a/backend/app/api/v1/entry.go +++ b/backend/app/api/v1/entry.go @@ -8,8 +8,9 @@ type ApiGroup struct { var ApiGroupApp = new(ApiGroup) +type BaseApi struct{} + var ( - authService = service.NewIAuthService() dashboardService = service.NewIDashboardService() appService = service.NewIAppService() @@ -54,7 +55,6 @@ var ( logService = service.NewILogService() snapshotService = service.NewISnapshotService() - upgradeService = service.NewIUpgradeService() runtimeService = service.NewRuntimeService() processService = service.NewIProcessService() diff --git a/backend/app/api/v1/logs.go b/backend/app/api/v1/logs.go index 72563328d..311b5159b 100644 --- a/backend/app/api/v1/logs.go +++ b/backend/app/api/v1/logs.go @@ -7,81 +7,6 @@ import ( "github.com/gin-gonic/gin" ) -// @Tags Logs -// @Summary Page login logs -// @Description 获取系统登录日志列表分页 -// @Accept json -// @Param request body dto.SearchLgLogWithPage true "request" -// @Success 200 {object} dto.PageResult -// @Security ApiKeyAuth -// @Router /logs/login [post] -func (b *BaseApi) GetLoginLogs(c *gin.Context) { - var req dto.SearchLgLogWithPage - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - total, list, err := logService.PageLoginLog(req) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - helper.SuccessWithData(c, dto.PageResult{ - Items: list, - Total: total, - }) -} - -// @Tags Logs -// @Summary Page operation logs -// @Description 获取系统操作日志列表分页 -// @Accept json -// @Param request body dto.SearchOpLogWithPage true "request" -// @Success 200 {object} dto.PageResult -// @Security ApiKeyAuth -// @Router /logs/operation [post] -func (b *BaseApi) GetOperationLogs(c *gin.Context) { - var req dto.SearchOpLogWithPage - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - total, list, err := logService.PageOperationLog(req) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - helper.SuccessWithData(c, dto.PageResult{ - Items: list, - Total: total, - }) -} - -// @Tags Logs -// @Summary Clean operation logs -// @Description 清空操作日志 -// @Accept json -// @Param request body dto.CleanLog true "request" -// @Success 200 {object} dto.PageResult -// @Security ApiKeyAuth -// @Router /logs/clean [post] -// @x-panel-log {"bodyKeys":["logType"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清空 [logType] 日志信息","formatEN":"Clean the [logType] log information"} -func (b *BaseApi) CleanLogs(c *gin.Context) { - var req dto.CleanLog - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if err := logService.CleanLogs(req.LogType); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - helper.SuccessWithData(c, nil) -} - // @Tags Logs // @Summary Load system log files // @Description 获取系统日志文件列表 diff --git a/backend/app/api/v1/setting.go b/backend/app/api/v1/setting.go index bcf9fed5f..561882cf0 100644 --- a/backend/app/api/v1/setting.go +++ b/backend/app/api/v1/setting.go @@ -1,16 +1,10 @@ package v1 import ( - "encoding/base64" - "errors" - "os" - "path" - "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/global" - "github.com/1Panel-dev/1Panel/backend/utils/mfa" "github.com/gin-gonic/gin" ) @@ -61,216 +55,6 @@ func (b *BaseApi) UpdateSetting(c *gin.Context) { helper.SuccessWithData(c, nil) } -// @Tags System Setting -// @Summary Update proxy setting -// @Description 服务器代理配置 -// @Accept json -// @Param request body dto.ProxyUpdate true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /settings/proxy/update [post] -// @x-panel-log {"bodyKeys":["proxyUrl","proxyPort"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"服务器代理配置 [proxyPort]:[proxyPort]","formatEN":"set proxy [proxyPort]:[proxyPort]."} -func (b *BaseApi) UpdateProxy(c *gin.Context) { - var req dto.ProxyUpdate - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if len(req.ProxyPasswd) != 0 && len(req.ProxyType) != 0 { - pass, err := base64.StdEncoding.DecodeString(req.ProxyPasswd) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) - return - } - req.ProxyPasswd = string(pass) - } - - if err := settingService.UpdateProxy(req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, nil) -} - -// @Tags System Setting -// @Summary Update system setting -// @Description 隐藏高级功能菜单 -// @Accept json -// @Param request body dto.SettingUpdate true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /settings/menu/update [post] -// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"隐藏高级功能菜单","formatEN":"Hide advanced feature menu."} -func (b *BaseApi) UpdateMenu(c *gin.Context) { - var req dto.SettingUpdate - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if err := settingService.Update(req.Key, req.Value); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, nil) -} - -// @Tags System Setting -// @Summary Update system password -// @Description 更新系统登录密码 -// @Accept json -// @Param request body dto.PasswordUpdate true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /settings/password/update [post] -// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统密码","formatEN":"update system password"} -func (b *BaseApi) UpdatePassword(c *gin.Context) { - var req dto.PasswordUpdate - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if err := settingService.UpdatePassword(c, req.OldPassword, req.NewPassword); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, nil) -} - -// @Tags System Setting -// @Summary Update system ssl -// @Description 修改系统 ssl 登录 -// @Accept json -// @Param request body dto.SSLUpdate true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /settings/ssl/update [post] -// @x-panel-log {"bodyKeys":["ssl"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统 ssl => [ssl]","formatEN":"update system ssl => [ssl]"} -func (b *BaseApi) UpdateSSL(c *gin.Context) { - var req dto.SSLUpdate - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if err := settingService.UpdateSSL(c, req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, nil) -} - -// @Tags System Setting -// @Summary Load system cert info -// @Description 获取证书信息 -// @Success 200 {object} dto.SettingInfo -// @Security ApiKeyAuth -// @Router /settings/ssl/info [get] -func (b *BaseApi) LoadFromCert(c *gin.Context) { - info, err := settingService.LoadFromCert() - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, info) -} - -// @Tags System Setting -// @Summary Download system cert -// @Description 下载证书 -// @Success 200 -// @Security ApiKeyAuth -// @Router /settings/ssl/download [post] -func (b *BaseApi) DownloadSSL(c *gin.Context) { - pathItem := path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt") - if _, err := os.Stat(pathItem); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - c.File(pathItem) -} - -// @Tags System Setting -// @Summary Load system address -// @Description 获取系统地址信息 -// @Accept json -// @Success 200 -// @Security ApiKeyAuth -// @Router /settings/interface [get] -func (b *BaseApi) LoadInterfaceAddr(c *gin.Context) { - data, err := settingService.LoadInterfaceAddr() - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, data) -} - -// @Tags System Setting -// @Summary Update system bind info -// @Description 更新系统监听信息 -// @Accept json -// @Param request body dto.BindInfo true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /settings/bind/update [post] -// @x-panel-log {"bodyKeys":["ipv6", "bindAddress"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统监听信息 => ipv6: [ipv6], 监听 IP: [bindAddress]","formatEN":"update system bind info => ipv6: [ipv6], 监听 IP: [bindAddress]"} -func (b *BaseApi) UpdateBindInfo(c *gin.Context) { - var req dto.BindInfo - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if err := settingService.UpdateBindInfo(req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, nil) -} - -// @Tags System Setting -// @Summary Update system port -// @Description 更新系统端口 -// @Accept json -// @Param request body dto.PortUpdate true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /settings/port/update [post] -// @x-panel-log {"bodyKeys":["serverPort"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统端口 => [serverPort]","formatEN":"update system port => [serverPort]"} -func (b *BaseApi) UpdatePort(c *gin.Context) { - var req dto.PortUpdate - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if err := settingService.UpdatePort(req.ServerPort); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, nil) -} - -// @Tags System Setting -// @Summary Reset system password expired -// @Description 重置过期系统登录密码 -// @Accept json -// @Param request body dto.PasswordUpdate true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /settings/expired/handle [post] -// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"重置过期密码","formatEN":"reset an expired Password"} -func (b *BaseApi) HandlePasswordExpired(c *gin.Context) { - var req dto.PasswordUpdate - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if err := settingService.HandlePasswordExpired(c, req.OldPassword, req.NewPassword); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, nil) -} - // @Tags System Setting // @Summary Load local backup dir // @Description 获取安装根目录 @@ -280,65 +64,3 @@ func (b *BaseApi) HandlePasswordExpired(c *gin.Context) { func (b *BaseApi) LoadBaseDir(c *gin.Context) { helper.SuccessWithData(c, global.CONF.System.DataDir) } - -// @Tags System Setting -// @Summary Load mfa info -// @Description 获取 mfa 信息 -// @Accept json -// @Param request body dto.MfaCredential true "request" -// @Success 200 {object} mfa.Otp -// @Security ApiKeyAuth -// @Router /settings/mfa [post] -func (b *BaseApi) LoadMFA(c *gin.Context) { - var req dto.MfaRequest - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - otp, err := mfa.GetOtp("admin", req.Title, req.Interval) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - helper.SuccessWithData(c, otp) -} - -// @Tags System Setting -// @Summary Bind mfa -// @Description Mfa 绑定 -// @Accept json -// @Param request body dto.MfaCredential true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /settings/mfa/bind [post] -// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"mfa 绑定","formatEN":"bind mfa"} -func (b *BaseApi) MFABind(c *gin.Context) { - var req dto.MfaCredential - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - success := mfa.ValidCode(req.Code, req.Interval, req.Secret) - if !success { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, errors.New("code is not valid")) - return - } - - if err := settingService.Update("MFAInterval", req.Interval); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - if err := settingService.Update("MFAStatus", "enable"); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - if err := settingService.Update("MFASecret", req.Secret); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - helper.SuccessWithData(c, nil) -} diff --git a/backend/app/api/v1/upgrade.go b/backend/app/api/v1/upgrade.go deleted file mode 100644 index 3853e616a..000000000 --- a/backend/app/api/v1/upgrade.go +++ /dev/null @@ -1,67 +0,0 @@ -package v1 - -import ( - "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" - "github.com/1Panel-dev/1Panel/backend/app/dto" - "github.com/1Panel-dev/1Panel/backend/constant" - "github.com/gin-gonic/gin" -) - -// @Tags System Setting -// @Summary Load upgrade info -// @Description 系统更新信息 -// @Success 200 {object} dto.UpgradeInfo -// @Security ApiKeyAuth -// @Router /settings/upgrade [get] -func (b *BaseApi) GetUpgradeInfo(c *gin.Context) { - info, err := upgradeService.SearchUpgrade() - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, info) -} - -// @Tags System Setting -// @Summary Load release notes by version -// @Description 获取版本 release notes -// @Accept json -// @Param request body dto.Upgrade true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /settings/upgrade [get] -func (b *BaseApi) GetNotesByVersion(c *gin.Context) { - var req dto.Upgrade - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - notes, err := upgradeService.LoadNotes(req) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, notes) -} - -// @Tags System Setting -// @Summary Upgrade -// @Description 系统更新 -// @Accept json -// @Param request body dto.Upgrade true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /settings/upgrade [post] -// @x-panel-log {"bodyKeys":["version"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新系统 => [version]","formatEN":"upgrade system => [version]"} -func (b *BaseApi) Upgrade(c *gin.Context) { - var req dto.Upgrade - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if err := upgradeService.Upgrade(req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, nil) -} diff --git a/backend/app/dto/auth.go b/backend/app/dto/auth.go deleted file mode 100644 index ccaa2ec12..000000000 --- a/backend/app/dto/auth.go +++ /dev/null @@ -1,40 +0,0 @@ -package dto - -type CaptchaResponse struct { - CaptchaID string `json:"captchaID"` - ImagePath string `json:"imagePath"` -} - -type UserLoginInfo struct { - Name string `json:"name"` - Token string `json:"token"` - MfaStatus string `json:"mfaStatus"` -} - -type MfaRequest struct { - Title string `json:"title" validate:"required"` - Interval int `json:"interval" validate:"required"` -} - -type MfaCredential struct { - Secret string `json:"secret" validate:"required"` - Code string `json:"code" validate:"required"` - Interval string `json:"interval" validate:"required"` -} - -type Login struct { - Name string `json:"name" validate:"required"` - Password string `json:"password" validate:"required"` - IgnoreCaptcha bool `json:"ignoreCaptcha"` - Captcha string `json:"captcha"` - CaptchaID string `json:"captchaID"` - AuthMethod string `json:"authMethod" validate:"required,oneof=jwt session"` - Language string `json:"language" validate:"required,oneof=zh en tw"` -} - -type MFALogin struct { - Name string `json:"name" validate:"required"` - Password string `json:"password" validate:"required"` - Code string `json:"code" validate:"required"` - AuthMethod string `json:"authMethod"` -} diff --git a/backend/app/dto/setting.go b/backend/app/dto/setting.go index 29f8b24a2..66c510c4e 100644 --- a/backend/app/dto/setting.go +++ b/backend/app/dto/setting.go @@ -3,52 +3,23 @@ package dto import "time" type SettingInfo struct { - UserName string `json:"userName"` - Email string `json:"email"` SystemIP string `json:"systemIP"` - SystemVersion string `json:"systemVersion"` DockerSockPath string `json:"dockerSockPath"` - DeveloperMode string `json:"developerMode"` + SystemVersion string `json:"systemVersion"` - SessionTimeout string `json:"sessionTimeout"` - LocalTime string `json:"localTime"` - TimeZone string `json:"timeZone"` - NtpSite string `json:"ntpSite"` + LocalTime string `json:"localTime"` + TimeZone string `json:"timeZone"` + NtpSite string `json:"ntpSite"` - Port string `json:"port"` - Ipv6 string `json:"ipv6"` - BindAddress string `json:"bindAddress"` - PanelName string `json:"panelName"` - Theme string `json:"theme"` - MenuTabs string `json:"menuTabs"` - Language string `json:"language"` DefaultNetwork string `json:"defaultNetwork"` LastCleanTime string `json:"lastCleanTime"` LastCleanSize string `json:"lastCleanSize"` LastCleanData string `json:"lastCleanData"` - ServerPort string `json:"serverPort"` - SSL string `json:"ssl"` - SSLType string `json:"sslType"` - BindDomain string `json:"bindDomain"` - AllowIPs string `json:"allowIPs"` - SecurityEntrance string `json:"securityEntrance"` - ExpirationDays string `json:"expirationDays"` - ExpirationTime string `json:"expirationTime"` - ComplexityVerification string `json:"complexityVerification"` - MFAStatus string `json:"mfaStatus"` - MFASecret string `json:"mfaSecret"` - MFAInterval string `json:"mfaInterval"` - MonitorStatus string `json:"monitorStatus"` MonitorInterval string `json:"monitorInterval"` MonitorStoreDays string `json:"monitorStoreDays"` - MessageType string `json:"messageType"` - EmailVars string `json:"emailVars"` - WeChatVars string `json:"weChatVars"` - DingVars string `json:"dingVars"` - AppStoreVersion string `json:"appStoreVersion"` AppStoreLastModified string `json:"appStoreLastModified"` AppStoreSyncStatus string `json:"appStoreSyncStatus"` @@ -56,15 +27,6 @@ type SettingInfo struct { FileRecycleBin string `json:"fileRecycleBin"` SnapshotIgnore string `json:"snapshotIgnore"` - XpackHideMenu string `json:"xpackHideMenu"` - NoAuthSetting string `json:"noAuthSetting"` - - ProxyUrl string `json:"proxyUrl"` - ProxyType string `json:"proxyType"` - ProxyPort string `json:"proxyPort"` - ProxyUser string `json:"proxyUser"` - ProxyPasswd string `json:"proxyPasswd"` - ProxyPasswdKeep string `json:"proxyPasswdKeep"` } type SettingUpdate struct { @@ -72,32 +34,6 @@ type SettingUpdate struct { Value string `json:"value"` } -type SSLUpdate struct { - SSLType string `json:"sslType" validate:"required,oneof=self select import import-paste import-local"` - Domain string `json:"domain"` - SSL string `json:"ssl" validate:"required,oneof=enable disable"` - Cert string `json:"cert"` - Key string `json:"key"` - SSLID uint `json:"sslID"` -} -type SSLInfo struct { - Domain string `json:"domain"` - Timeout string `json:"timeout"` - RootPath string `json:"rootPath"` - Cert string `json:"cert"` - Key string `json:"key"` - SSLID uint `json:"sslID"` -} - -type PasswordUpdate struct { - OldPassword string `json:"oldPassword" validate:"required"` - NewPassword string `json:"newPassword" validate:"required"` -} - -type PortUpdate struct { - ServerPort uint `json:"serverPort" validate:"required,number,max=65535,min=1"` -} - type SnapshotStatus struct { Panel string `json:"panel"` PanelInfo string `json:"panelInfo"` @@ -128,11 +64,13 @@ type SnapshotBatchDelete struct { DeleteWithFile bool `json:"deleteWithFile"` Ids []uint `json:"ids" validate:"required"` } + type SnapshotImport struct { From string `json:"from"` Names []string `json:"names"` Description string `json:"description" validate:"max=256"` } + type SnapshotInfo struct { ID uint `json:"id"` Name string `json:"name"` @@ -154,35 +92,10 @@ type SnapshotInfo struct { LastRollbackedAt string `json:"lastRollbackedAt"` } -type UpgradeInfo struct { - TestVersion string `json:"testVersion"` - NewVersion string `json:"newVersion"` - LatestVersion string `json:"latestVersion"` - ReleaseNote string `json:"releaseNote"` -} - type SyncTime struct { NtpSite string `json:"ntpSite" validate:"required"` } -type BindInfo struct { - Ipv6 string `json:"ipv6" validate:"required,oneof=enable disable"` - BindAddress string `json:"bindAddress" validate:"required"` -} - -type Upgrade struct { - Version string `json:"version" validate:"required"` -} - -type ProxyUpdate struct { - ProxyUrl string `json:"proxyUrl"` - ProxyType string `json:"proxyType"` - ProxyPort string `json:"proxyPort"` - ProxyUser string `json:"proxyUser"` - ProxyPasswd string `json:"proxyPasswd"` - ProxyPasswdKeep string `json:"proxyPasswdKeep"` -} - type CleanData struct { SystemClean []CleanTree `json:"systemClean"` UploadClean []CleanTree `json:"uploadClean"` @@ -209,12 +122,3 @@ type Clean struct { Name string `json:"name"` Size uint64 `json:"size"` } - -type XpackHideMenu struct { - ID string `json:"id"` - Label string `json:"label"` - IsCheck bool `json:"isCheck"` - Title string `json:"title"` - Path string `json:"path,omitempty"` - Children []XpackHideMenu `json:"children,omitempty"` -} diff --git a/backend/app/model/logs.go b/backend/app/model/logs.go deleted file mode 100644 index 4018f4322..000000000 --- a/backend/app/model/logs.go +++ /dev/null @@ -1,31 +0,0 @@ -package model - -import ( - "time" -) - -type OperationLog struct { - BaseModel - Source string `gorm:"type:varchar(64)" json:"source"` - - IP string `gorm:"type:varchar(64)" json:"ip"` - Path string `gorm:"type:varchar(64)" json:"path"` - Method string `gorm:"type:varchar(64)" json:"method"` - UserAgent string `gorm:"type:varchar(256)" json:"userAgent"` - - Latency time.Duration `gorm:"type:varchar(64)" json:"latency"` - Status string `gorm:"type:varchar(64)" json:"status"` - Message string `gorm:"type:varchar(256)" json:"message"` - - DetailZH string `gorm:"type:varchar(256)" json:"detailZH"` - DetailEN string `gorm:"type:varchar(256)" json:"detailEN"` -} - -type LoginLog struct { - BaseModel - IP string `gorm:"type:varchar(64)" json:"ip"` - Address string `gorm:"type:varchar(64)" json:"address"` - Agent string `gorm:"type:varchar(256)" json:"agent"` - Status string `gorm:"type:varchar(64)" json:"status"` - Message string `gorm:"type:longText" json:"message"` -} diff --git a/backend/app/repo/logs.go b/backend/app/repo/logs.go deleted file mode 100644 index 5309ee6b7..000000000 --- a/backend/app/repo/logs.go +++ /dev/null @@ -1,101 +0,0 @@ -package repo - -import ( - "github.com/1Panel-dev/1Panel/backend/app/model" - "github.com/1Panel-dev/1Panel/backend/global" - "gorm.io/gorm" -) - -type LogRepo struct{} - -type ILogRepo interface { - CleanLogin() error - CreateLoginLog(user *model.LoginLog) error - PageLoginLog(limit, offset int, opts ...DBOption) (int64, []model.LoginLog, error) - - WithByIP(ip string) DBOption - WithByStatus(status string) DBOption - WithByGroup(group string) DBOption - WithByLikeOperation(operation string) DBOption - CleanOperation() error - CreateOperationLog(user *model.OperationLog) error - PageOperationLog(limit, offset int, opts ...DBOption) (int64, []model.OperationLog, error) -} - -func NewILogRepo() ILogRepo { - return &LogRepo{} -} - -func (u *LogRepo) CleanLogin() error { - return global.DB.Exec("delete from login_logs;").Error -} - -func (u *LogRepo) CreateLoginLog(log *model.LoginLog) error { - return global.DB.Create(log).Error -} - -func (u *LogRepo) PageLoginLog(page, size int, opts ...DBOption) (int64, []model.LoginLog, error) { - var ops []model.LoginLog - db := global.DB.Model(&model.LoginLog{}) - for _, opt := range opts { - db = opt(db) - } - count := int64(0) - db = db.Count(&count) - err := db.Limit(size).Offset(size * (page - 1)).Find(&ops).Error - return count, ops, err -} - -func (u *LogRepo) CleanOperation() error { - return global.DB.Exec("delete from operation_logs").Error -} - -func (u *LogRepo) CreateOperationLog(log *model.OperationLog) error { - return global.DB.Create(log).Error -} - -func (u *LogRepo) PageOperationLog(page, size int, opts ...DBOption) (int64, []model.OperationLog, error) { - var ops []model.OperationLog - db := global.DB.Model(&model.OperationLog{}) - for _, opt := range opts { - db = opt(db) - } - count := int64(0) - db = db.Count(&count) - err := db.Limit(size).Offset(size * (page - 1)).Find(&ops).Error - return count, ops, err -} - -func (c *LogRepo) WithByStatus(status string) DBOption { - return func(g *gorm.DB) *gorm.DB { - if len(status) == 0 { - return g - } - return g.Where("status = ?", status) - } -} -func (c *LogRepo) WithByGroup(group string) DBOption { - return func(g *gorm.DB) *gorm.DB { - if len(group) == 0 { - return g - } - return g.Where("source = ?", group) - } -} -func (c *LogRepo) WithByIP(ip string) DBOption { - return func(g *gorm.DB) *gorm.DB { - if len(ip) == 0 { - return g - } - return g.Where("ip LIKE ?", "%"+ip+"%") - } -} -func (c *LogRepo) WithByLikeOperation(operation string) DBOption { - return func(g *gorm.DB) *gorm.DB { - if len(operation) == 0 { - return g - } - infoStr := "%" + operation + "%" - return g.Where("detail_zh LIKE ? OR detail_en LIKE ?", infoStr, infoStr) - } -} diff --git a/backend/app/service/auth.go b/backend/app/service/auth.go deleted file mode 100644 index 118ffd982..000000000 --- a/backend/app/service/auth.go +++ /dev/null @@ -1,196 +0,0 @@ -package service - -import ( - "crypto/hmac" - "strconv" - - "github.com/1Panel-dev/1Panel/backend/app/dto" - "github.com/1Panel-dev/1Panel/backend/buserr" - "github.com/1Panel-dev/1Panel/backend/constant" - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/1Panel-dev/1Panel/backend/utils/encrypt" - "github.com/1Panel-dev/1Panel/backend/utils/jwt" - "github.com/1Panel-dev/1Panel/backend/utils/mfa" - "github.com/gin-gonic/gin" - "github.com/google/uuid" - "github.com/pkg/errors" -) - -type AuthService struct{} - -type IAuthService interface { - CheckIsSafety(code string) (string, error) - GetResponsePage() (string, error) - VerifyCode(code string) (bool, error) - Login(c *gin.Context, info dto.Login, entrance string) (*dto.UserLoginInfo, error) - LogOut(c *gin.Context) error - MFALogin(c *gin.Context, info dto.MFALogin, entrance string) (*dto.UserLoginInfo, error) -} - -func NewIAuthService() IAuthService { - return &AuthService{} -} - -func (u *AuthService) Login(c *gin.Context, info dto.Login, entrance string) (*dto.UserLoginInfo, error) { - nameSetting, err := settingRepo.Get(settingRepo.WithByKey("UserName")) - if err != nil { - return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error()) - } - passwordSetting, err := settingRepo.Get(settingRepo.WithByKey("Password")) - if err != nil { - return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error()) - } - pass, err := encrypt.StringDecrypt(passwordSetting.Value) - if err != nil { - return nil, constant.ErrAuth - } - if !hmac.Equal([]byte(info.Password), []byte(pass)) || nameSetting.Value != info.Name { - return nil, constant.ErrAuth - } - entranceSetting, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance")) - if err != nil { - return nil, err - } - if len(entranceSetting.Value) != 0 && entranceSetting.Value != entrance { - return nil, buserr.New(constant.ErrEntrance) - } - mfa, err := settingRepo.Get(settingRepo.WithByKey("MFAStatus")) - if err != nil { - return nil, err - } - if err = settingRepo.Update("Language", info.Language); err != nil { - return nil, err - } - if mfa.Value == "enable" { - return &dto.UserLoginInfo{Name: nameSetting.Value, MfaStatus: mfa.Value}, nil - } - return u.generateSession(c, info.Name, info.AuthMethod) -} - -func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin, entrance string) (*dto.UserLoginInfo, error) { - nameSetting, err := settingRepo.Get(settingRepo.WithByKey("UserName")) - if err != nil { - return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error()) - } - passwordSetting, err := settingRepo.Get(settingRepo.WithByKey("Password")) - if err != nil { - return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error()) - } - pass, err := encrypt.StringDecrypt(passwordSetting.Value) - if err != nil { - return nil, err - } - if !hmac.Equal([]byte(info.Password), []byte(pass)) || nameSetting.Value != info.Name { - return nil, constant.ErrAuth - } - entranceSetting, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance")) - if err != nil { - return nil, err - } - if len(entranceSetting.Value) != 0 && entranceSetting.Value != entrance { - return nil, buserr.New(constant.ErrEntrance) - } - mfaSecret, err := settingRepo.Get(settingRepo.WithByKey("MFASecret")) - if err != nil { - return nil, err - } - mfaInterval, err := settingRepo.Get(settingRepo.WithByKey("MFAInterval")) - if err != nil { - return nil, err - } - success := mfa.ValidCode(info.Code, mfaInterval.Value, mfaSecret.Value) - if !success { - return nil, constant.ErrAuth - } - - return u.generateSession(c, info.Name, info.AuthMethod) -} - -func (u *AuthService) generateSession(c *gin.Context, name, authMethod string) (*dto.UserLoginInfo, error) { - setting, err := settingRepo.Get(settingRepo.WithByKey("SessionTimeout")) - if err != nil { - return nil, err - } - httpsSetting, err := settingRepo.Get(settingRepo.WithByKey("SSL")) - if err != nil { - return nil, err - } - lifeTime, err := strconv.Atoi(setting.Value) - if err != nil { - return nil, err - } - - if authMethod == constant.AuthMethodJWT { - j := jwt.NewJWT() - claims := j.CreateClaims(jwt.BaseClaims{ - Name: name, - }) - token, err := j.CreateToken(claims) - if err != nil { - return nil, err - } - return &dto.UserLoginInfo{Name: name, Token: token}, nil - } - sID, _ := c.Cookie(constant.SessionName) - sessionUser, err := global.SESSION.Get(sID) - if err != nil { - sID = uuid.New().String() - c.SetCookie(constant.SessionName, sID, 0, "", "", httpsSetting.Value == "enable", true) - err := global.SESSION.Set(sID, sessionUser, lifeTime) - if err != nil { - return nil, err - } - return &dto.UserLoginInfo{Name: name}, nil - } - if err := global.SESSION.Set(sID, sessionUser, lifeTime); err != nil { - return nil, err - } - - return &dto.UserLoginInfo{Name: name}, nil -} - -func (u *AuthService) LogOut(c *gin.Context) error { - httpsSetting, err := settingRepo.Get(settingRepo.WithByKey("SSL")) - if err != nil { - return err - } - sID, _ := c.Cookie(constant.SessionName) - if sID != "" { - c.SetCookie(constant.SessionName, sID, -1, "", "", httpsSetting.Value == "enable", true) - err := global.SESSION.Delete(sID) - if err != nil { - return err - } - } - return nil -} - -func (u *AuthService) VerifyCode(code string) (bool, error) { - setting, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance")) - if err != nil { - return false, err - } - return hmac.Equal([]byte(setting.Value), []byte(code)), nil -} - -func (u *AuthService) CheckIsSafety(code string) (string, error) { - status, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance")) - if err != nil { - return "", err - } - if len(status.Value) == 0 { - return "disable", nil - } - if status.Value == code { - return "pass", nil - } - return "unpass", nil -} - -func (u *AuthService) GetResponsePage() (string, error) { - pageCode, err := settingRepo.Get(settingRepo.WithByKey("NoAuthSetting")) - if err != nil { - return "", err - } - return pageCode.Value, nil -} diff --git a/backend/app/service/clam.go b/backend/app/service/clam.go index e54c4f3d5..75c3371e4 100644 --- a/backend/app/service/clam.go +++ b/backend/app/service/clam.go @@ -268,7 +268,7 @@ func (c *ClamService) Delete(req dto.ClamDelete) error { } func (c *ClamService) HandleOnce(req dto.OperateByID) error { - if cmd.Which("clamdscan") == false { + if !cmd.Which("clamdscan") { return buserr.New("ErrClamdscanNotFound") } clam, _ := clamRepo.Get(commonRepo.WithByID(req.ID)) diff --git a/backend/app/service/entry.go b/backend/app/service/entry.go index 2c72dee06..59c1d6d42 100644 --- a/backend/app/service/entry.go +++ b/backend/app/service/entry.go @@ -37,7 +37,6 @@ var ( websiteAcmeRepo = repo.NewIAcmeAccountRepo() websiteCARepo = repo.NewIWebsiteCARepo() - logRepo = repo.NewILogRepo() snapshotRepo = repo.NewISnapshotRepo() runtimeRepo = repo.NewIRunTimeRepo() diff --git a/backend/app/service/file.go b/backend/app/service/file.go index b48191fc6..76dced4d8 100644 --- a/backend/app/service/file.go +++ b/backend/app/service/file.go @@ -141,7 +141,7 @@ func shouldFilterPath(path string) bool { func (f *FileService) buildFileTree(node *response.FileTree, items []*files.FileInfo, op request.FileOption, level int) error { for _, v := range items { if shouldFilterPath(v.Path) { - global.LOG.Info("File Tree: Skipping %s due to filter\n", v.Path) + global.LOG.Infof("File Tree: Skipping %s due to filter\n", v.Path) continue } childNode := response.FileTree{ @@ -167,7 +167,7 @@ func (f *FileService) buildChildNode(childNode *response.FileTree, fileInfo *fil subInfo, err := files.NewFileInfo(op.FileOption) if err != nil { if os.IsPermission(err) || errors.Is(err, unix.EACCES) { - global.LOG.Info("File Tree: Skipping %s due to permission denied\n", fileInfo.Path) + global.LOG.Infof("File Tree: Skipping %s due to permission denied\n", fileInfo.Path) return nil } global.LOG.Errorf("File Tree: Skipping %s due to error: %s\n", fileInfo.Path, err.Error()) diff --git a/backend/app/service/image.go b/backend/app/service/image.go index 4a5190919..833b6652b 100644 --- a/backend/app/service/image.go +++ b/backend/app/service/image.go @@ -432,7 +432,7 @@ func (u *ImageService) ImageRemove(req dto.BatchDelete) error { } defer client.Close() for _, id := range req.Names { - if _, err := client.ImageRemove(context.TODO(), id, types.ImageRemoveOptions{Force: req.Force, PruneChildren: true}); err != nil { + if _, err := client.ImageRemove(context.TODO(), id, image.RemoveOptions{Force: req.Force, PruneChildren: true}); err != nil { if strings.Contains(err.Error(), "image is being used") || strings.Contains(err.Error(), "is using") { if strings.Contains(id, "sha256:") { return buserr.New(constant.ErrObjectInUsed) diff --git a/backend/app/service/logs.go b/backend/app/service/logs.go index 41c2b7ffe..51cdad04e 100644 --- a/backend/app/service/logs.go +++ b/backend/app/service/logs.go @@ -9,41 +9,21 @@ import ( "strings" "time" - "github.com/1Panel-dev/1Panel/backend/app/dto" - "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/buserr" - "github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/global" - "github.com/1Panel-dev/1Panel/backend/utils/cmd" - "github.com/jinzhu/copier" - "github.com/pkg/errors" ) type LogService struct{} -const logs = "https://resource.fit2cloud.com/installation-log.sh" - type ILogService interface { ListSystemLogFile() ([]string, error) - CreateLoginLog(operation model.LoginLog) error - PageLoginLog(search dto.SearchLgLogWithPage) (int64, interface{}, error) - - CreateOperationLog(operation model.OperationLog) error - PageOperationLog(search dto.SearchOpLogWithPage) (int64, interface{}, error) - LoadSystemLog(name string) (string, error) - - CleanLogs(logtype string) error } func NewILogService() ILogService { return &LogService{} } -func (u *LogService) CreateLoginLog(operation model.LoginLog) error { - return logRepo.CreateLoginLog(&operation) -} - func (u *LogService) ListSystemLogFile() ([]string, error) { logDir := path.Join(global.CONF.System.BaseDir, "1panel/log") var files []string @@ -77,49 +57,6 @@ func (u *LogService) ListSystemLogFile() ([]string, error) { return files, nil } -func (u *LogService) PageLoginLog(req dto.SearchLgLogWithPage) (int64, interface{}, error) { - total, ops, err := logRepo.PageLoginLog( - req.Page, - req.PageSize, - logRepo.WithByIP(req.IP), - logRepo.WithByStatus(req.Status), - commonRepo.WithOrderBy("created_at desc"), - ) - var dtoOps []dto.LoginLog - for _, op := range ops { - var item dto.LoginLog - if err := copier.Copy(&item, &op); err != nil { - return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error()) - } - dtoOps = append(dtoOps, item) - } - return total, dtoOps, err -} - -func (u *LogService) CreateOperationLog(operation model.OperationLog) error { - return logRepo.CreateOperationLog(&operation) -} - -func (u *LogService) PageOperationLog(req dto.SearchOpLogWithPage) (int64, interface{}, error) { - total, ops, err := logRepo.PageOperationLog( - req.Page, - req.PageSize, - logRepo.WithByGroup(req.Source), - logRepo.WithByLikeOperation(req.Operation), - logRepo.WithByStatus(req.Status), - commonRepo.WithOrderBy("created_at desc"), - ) - var dtoOps []dto.OperationLog - for _, op := range ops { - var item dto.OperationLog - if err := copier.Copy(&item, &op); err != nil { - return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error()) - } - dtoOps = append(dtoOps, item) - } - return total, dtoOps, err -} - func (u *LogService) LoadSystemLog(name string) (string, error) { if name == time.Now().Format("2006-01-02") { name = "1Panel.log" @@ -142,14 +79,3 @@ func (u *LogService) LoadSystemLog(name string) (string, error) { } return string(content), nil } - -func (u *LogService) CleanLogs(logtype string) error { - if logtype == "operation" { - return logRepo.CleanOperation() - } - return logRepo.CleanLogin() -} - -func writeLogs(version string) { - _, _ = cmd.Execf("curl -sfL %s | sh -s 1p upgrade %s", logs, version) -} diff --git a/backend/app/service/setting.go b/backend/app/service/setting.go index 0bbf3b68b..9cb8518be 100644 --- a/backend/app/service/setting.go +++ b/backend/app/service/setting.go @@ -1,29 +1,12 @@ package service import ( - "crypto/tls" - "crypto/x509" "encoding/json" - "encoding/pem" - "fmt" - "net" - "os" - "path" - "strconv" - "strings" "time" - "github.com/1Panel-dev/1Panel/backend/app/dto/request" - "github.com/1Panel-dev/1Panel/backend/app/dto" - "github.com/1Panel-dev/1Panel/backend/buserr" "github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/global" - "github.com/1Panel-dev/1Panel/backend/utils/cmd" - "github.com/1Panel-dev/1Panel/backend/utils/common" - "github.com/1Panel-dev/1Panel/backend/utils/encrypt" - "github.com/1Panel-dev/1Panel/backend/utils/files" - "github.com/gin-gonic/gin" "github.com/robfig/cron/v3" ) @@ -31,15 +14,7 @@ type SettingService struct{} type ISettingService interface { GetSettingInfo() (*dto.SettingInfo, error) - LoadInterfaceAddr() ([]string, error) Update(key, value string) error - UpdateProxy(req dto.ProxyUpdate) error - UpdatePassword(c *gin.Context, old, new string) error - UpdatePort(port uint) error - UpdateBindInfo(req dto.BindInfo) error - UpdateSSL(c *gin.Context, req dto.SSLUpdate) error - LoadFromCert() (*dto.SSLInfo, error) - HandlePasswordExpired(c *gin.Context, old, new string) error } func NewISettingService() ISettingService { @@ -63,11 +38,6 @@ func (u *SettingService) GetSettingInfo() (*dto.SettingInfo, error) { if err := json.Unmarshal(arr, &info); err != nil { return nil, err } - if info.ProxyPasswdKeep != constant.StatusEnable { - info.ProxyPasswd = "" - } else { - info.ProxyPasswd, _ = encrypt.StringDecrypt(info.ProxyPasswd) - } info.LocalTime = time.Now().Format("2006-01-02 15:04:05 MST -0700") return &info, err @@ -112,373 +82,5 @@ func (u *SettingService) Update(key, value string) error { return err } - switch key { - case "ExpirationDays": - timeout, err := strconv.Atoi(value) - if err != nil { - return err - } - if err := settingRepo.Update("ExpirationTime", time.Now().AddDate(0, 0, timeout).Format(constant.DateTimeLayout)); err != nil { - return err - } - case "BindDomain": - if len(value) != 0 { - _ = global.SESSION.Clean() - } - case "UserName", "Password": - _ = global.SESSION.Clean() - - } - - return nil -} - -func (u *SettingService) LoadInterfaceAddr() ([]string, error) { - addrMap := make(map[string]struct{}) - addrs, err := net.InterfaceAddrs() - if err != nil { - return nil, err - } - for _, addr := range addrs { - ipNet, ok := addr.(*net.IPNet) - if ok && ipNet.IP.To16() != nil { - addrMap[ipNet.IP.String()] = struct{}{} - } - } - var data []string - for key := range addrMap { - data = append(data, key) - } - return data, nil -} - -func (u *SettingService) UpdateBindInfo(req dto.BindInfo) error { - if err := settingRepo.Update("Ipv6", req.Ipv6); err != nil { - return err - } - if err := settingRepo.Update("BindAddress", req.BindAddress); err != nil { - return err - } - go func() { - time.Sleep(1 * time.Second) - _, err := cmd.Exec("systemctl restart 1panel.service") - if err != nil { - global.LOG.Errorf("restart system with new bind info failed, err: %v", err) - } - }() - return nil -} - -func (u *SettingService) UpdateProxy(req dto.ProxyUpdate) error { - if err := settingRepo.Update("ProxyUrl", req.ProxyUrl); err != nil { - return err - } - if err := settingRepo.Update("ProxyType", req.ProxyType); err != nil { - return err - } - if err := settingRepo.Update("ProxyPort", req.ProxyPort); err != nil { - return err - } - if err := settingRepo.Update("ProxyUser", req.ProxyUser); err != nil { - return err - } - pass, _ := encrypt.StringEncrypt(req.ProxyPasswd) - if err := settingRepo.Update("ProxyPasswd", pass); err != nil { - return err - } - if err := settingRepo.Update("ProxyPasswdKeep", req.ProxyPasswdKeep); err != nil { - return err - } - return nil -} - -func (u *SettingService) UpdatePort(port uint) error { - if common.ScanPort(int(port)) { - return buserr.WithDetail(constant.ErrPortInUsed, port, nil) - } - serverPort, err := settingRepo.Get(settingRepo.WithByKey("ServerPort")) - if err != nil { - return err - } - portValue, _ := strconv.Atoi(serverPort.Value) - if err := OperateFirewallPort([]int{portValue}, []int{int(port)}); err != nil { - global.LOG.Errorf("set system firewall ports failed, err: %v", err) - } - if err := settingRepo.Update("ServerPort", strconv.Itoa(int(port))); err != nil { - return err - } - go func() { - time.Sleep(1 * time.Second) - _, err := cmd.Exec("systemctl restart 1panel.service") - if err != nil { - global.LOG.Errorf("restart system port failed, err: %v", err) - } - }() - return nil -} - -func (u *SettingService) UpdateSSL(c *gin.Context, req dto.SSLUpdate) error { - secretDir := path.Join(global.CONF.System.BaseDir, "1panel/secret") - if req.SSL == "disable" { - if err := settingRepo.Update("SSL", "disable"); err != nil { - return err - } - if err := settingRepo.Update("SSLType", "self"); err != nil { - return err - } - _ = os.Remove(path.Join(secretDir, "server.crt")) - _ = os.Remove(path.Join(secretDir, "server.key")) - sID, _ := c.Cookie(constant.SessionName) - c.SetCookie(constant.SessionName, sID, 0, "", "", false, true) - - go func() { - _, err := cmd.Exec("systemctl restart 1panel.service") - if err != nil { - global.LOG.Errorf("restart system failed, err: %v", err) - } - }() - return nil - } - if _, err := os.Stat(secretDir); err != nil && os.IsNotExist(err) { - if err = os.MkdirAll(secretDir, os.ModePerm); err != nil { - return err - } - } - if err := settingRepo.Update("SSLType", req.SSLType); err != nil { - return err - } - var ( - secret string - key string - ) - - switch req.SSLType { - case "self": - if len(req.Domain) == 0 { - return fmt.Errorf("load domain failed") - } - defaultCA, err := websiteCARepo.GetFirst(commonRepo.WithByName("1Panel")) - if err != nil { - return err - } - websiteSSL, err := NewIWebsiteCAService().ObtainSSL(request.WebsiteCAObtain{ - ID: defaultCA.ID, - KeyType: "P256", - Domains: req.Domain, - Time: 1, - Unit: "year", - AutoRenew: true, - }) - if err != nil { - return err - } - secret = websiteSSL.Pem - key = websiteSSL.PrivateKey - if err := settingRepo.Update("SSLID", strconv.Itoa(int(websiteSSL.ID))); err != nil { - return err - } - case "select": - websiteSSL, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(req.SSLID)) - if err != nil { - return err - } - secret = websiteSSL.Pem - key = websiteSSL.PrivateKey - if err := settingRepo.Update("SSLID", strconv.Itoa(int(req.SSLID))); err != nil { - return err - } - case "import-paste": - secret = req.Cert - key = req.Key - case "import-local": - keyFile, err := os.ReadFile(req.Key) - if err != nil { - return err - } - key = string(keyFile) - certFile, err := os.ReadFile(req.Cert) - if err != nil { - return err - } - secret = string(certFile) - } - - fileOp := files.NewFileOp() - if err := fileOp.WriteFile(path.Join(secretDir, "server.crt.tmp"), strings.NewReader(secret), 0600); err != nil { - return err - } - if err := fileOp.WriteFile(path.Join(secretDir, "server.key.tmp"), strings.NewReader(key), 0600); err != nil { - return err - } - if err := checkCertValid(); err != nil { - return err - } - if err := fileOp.Rename(path.Join(secretDir, "server.crt.tmp"), path.Join(secretDir, "server.crt")); err != nil { - return err - } - if err := fileOp.Rename(path.Join(secretDir, "server.key.tmp"), path.Join(secretDir, "server.key")); err != nil { - return err - } - if err := settingRepo.Update("SSL", req.SSL); err != nil { - return err - } - - sID, _ := c.Cookie(constant.SessionName) - c.SetCookie(constant.SessionName, sID, 0, "", "", true, true) - go func() { - time.Sleep(1 * time.Second) - _, err := cmd.Exec("systemctl restart 1panel.service") - if err != nil { - global.LOG.Errorf("restart system failed, err: %v", err) - } - }() - return nil -} - -func (u *SettingService) LoadFromCert() (*dto.SSLInfo, error) { - ssl, err := settingRepo.Get(settingRepo.WithByKey("SSL")) - if err != nil { - return nil, err - } - if ssl.Value == "disable" { - return &dto.SSLInfo{}, nil - } - sslType, err := settingRepo.Get(settingRepo.WithByKey("SSLType")) - if err != nil { - return nil, err - } - var data dto.SSLInfo - switch sslType.Value { - case "self": - data, err = loadInfoFromCert() - if err != nil { - return nil, err - } - case "import": - data, err = loadInfoFromCert() - if err != nil { - return nil, err - } - if _, err := os.Stat(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt")); err != nil { - return nil, fmt.Errorf("load server.crt file failed, err: %v", err) - } - certFile, _ := os.ReadFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt")) - data.Cert = string(certFile) - - if _, err := os.Stat(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.key")); err != nil { - return nil, fmt.Errorf("load server.key file failed, err: %v", err) - } - keyFile, _ := os.ReadFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.key")) - data.Key = string(keyFile) - case "select": - sslID, err := settingRepo.Get(settingRepo.WithByKey("SSLID")) - if err != nil { - return nil, err - } - id, _ := strconv.Atoi(sslID.Value) - ssl, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(uint(id))) - if err != nil { - return nil, err - } - data.Domain = ssl.Domains - data.SSLID = uint(id) - data.Timeout = ssl.ExpireDate.Format(constant.DateTimeLayout) - } - return &data, nil -} - -func (u *SettingService) HandlePasswordExpired(c *gin.Context, old, new string) error { - setting, err := settingRepo.Get(settingRepo.WithByKey("Password")) - if err != nil { - return err - } - passwordFromDB, err := encrypt.StringDecrypt(setting.Value) - if err != nil { - return err - } - if passwordFromDB == old { - newPassword, err := encrypt.StringEncrypt(new) - if err != nil { - return err - } - if err := settingRepo.Update("Password", newPassword); err != nil { - return err - } - - expiredSetting, err := settingRepo.Get(settingRepo.WithByKey("ExpirationDays")) - if err != nil { - return err - } - timeout, _ := strconv.Atoi(expiredSetting.Value) - if err := settingRepo.Update("ExpirationTime", time.Now().AddDate(0, 0, timeout).Format(constant.DateTimeLayout)); err != nil { - return err - } - return nil - } - return constant.ErrInitialPassword -} - -func (u *SettingService) UpdatePassword(c *gin.Context, old, new string) error { - if err := u.HandlePasswordExpired(c, old, new); err != nil { - return err - } - _ = global.SESSION.Clean() - return nil -} - -func loadInfoFromCert() (dto.SSLInfo, error) { - var info dto.SSLInfo - certFile := path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt") - if _, err := os.Stat(certFile); err != nil { - return info, err - } - certData, err := os.ReadFile(certFile) - if err != nil { - return info, err - } - certBlock, _ := pem.Decode(certData) - if certBlock == nil { - return info, err - } - certObj, err := x509.ParseCertificate(certBlock.Bytes) - if err != nil { - return info, err - } - var domains []string - if len(certObj.IPAddresses) != 0 { - for _, ip := range certObj.IPAddresses { - domains = append(domains, ip.String()) - } - } - if len(certObj.DNSNames) != 0 { - domains = append(domains, certObj.DNSNames...) - } - return dto.SSLInfo{ - Domain: strings.Join(domains, ","), - Timeout: certObj.NotAfter.Format(constant.DateTimeLayout), - RootPath: path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt"), - }, nil -} - -func checkCertValid() error { - certificate, err := os.ReadFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt.tmp")) - if err != nil { - return err - } - key, err := os.ReadFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.key.tmp")) - if err != nil { - return err - } - if _, err = tls.X509KeyPair(certificate, key); err != nil { - return err - } - certBlock, _ := pem.Decode(certificate) - if certBlock == nil { - return err - } - if _, err := x509.ParseCertificate(certBlock.Bytes); err != nil { - return err - } - return nil } diff --git a/backend/app/service/snapshot.go b/backend/app/service/snapshot.go index 8d53201b2..07f14bfdd 100644 --- a/backend/app/service/snapshot.go +++ b/backend/app/service/snapshot.go @@ -48,6 +48,9 @@ func NewISnapshotService() ISnapshotService { func (u *SnapshotService) SearchWithPage(req dto.SearchWithPage) (int64, interface{}, error) { total, systemBackups, err := snapshotRepo.Page(req.Page, req.PageSize, commonRepo.WithLikeName(req.Info)) + if err != nil { + return 0, nil, err + } dtoSnap, err := loadSnapSize(systemBackups) if err != nil { return 0, nil, err diff --git a/backend/app/service/upgrade.go b/backend/app/service/upgrade.go deleted file mode 100644 index b2d2fdad9..000000000 --- a/backend/app/service/upgrade.go +++ /dev/null @@ -1,351 +0,0 @@ -package service - -import ( - "encoding/json" - "fmt" - "net/http" - "os" - "path" - "strconv" - "strings" - "time" - - "github.com/1Panel-dev/1Panel/backend/app/dto" - "github.com/1Panel-dev/1Panel/backend/constant" - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/1Panel-dev/1Panel/backend/utils/cmd" - "github.com/1Panel-dev/1Panel/backend/utils/common" - "github.com/1Panel-dev/1Panel/backend/utils/files" - httpUtil "github.com/1Panel-dev/1Panel/backend/utils/http" -) - -type UpgradeService struct{} - -type IUpgradeService interface { - Upgrade(req dto.Upgrade) error - LoadNotes(req dto.Upgrade) (string, error) - SearchUpgrade() (*dto.UpgradeInfo, error) -} - -func NewIUpgradeService() IUpgradeService { - return &UpgradeService{} -} - -func (u *UpgradeService) SearchUpgrade() (*dto.UpgradeInfo, error) { - var upgrade dto.UpgradeInfo - currentVersion, err := settingRepo.Get(settingRepo.WithByKey("SystemVersion")) - if err != nil { - return nil, err - } - DeveloperMode, err := settingRepo.Get(settingRepo.WithByKey("DeveloperMode")) - if err != nil { - return nil, err - } - - upgrade.TestVersion, upgrade.NewVersion, upgrade.LatestVersion = u.loadVersionByMode(DeveloperMode.Value, currentVersion.Value) - var itemVersion string - if len(upgrade.LatestVersion) != 0 { - itemVersion = upgrade.LatestVersion - } - if len(upgrade.NewVersion) != 0 { - itemVersion = upgrade.NewVersion - } - if (global.CONF.System.Mode == "dev" || DeveloperMode.Value == "enable") && len(upgrade.TestVersion) != 0 { - itemVersion = upgrade.TestVersion - } - if len(itemVersion) == 0 { - return &upgrade, nil - } - mode := global.CONF.System.Mode - if strings.Contains(itemVersion, "beta") { - mode = "beta" - } - notes, err := u.loadReleaseNotes(fmt.Sprintf("%s/%s/%s/release/1panel-%s-release-notes", global.CONF.System.RepoUrl, mode, itemVersion, itemVersion)) - if err != nil { - return nil, fmt.Errorf("load releases-notes of version %s failed, err: %v", itemVersion, err) - } - upgrade.ReleaseNote = notes - return &upgrade, nil -} - -func (u *UpgradeService) LoadNotes(req dto.Upgrade) (string, error) { - mode := global.CONF.System.Mode - if strings.Contains(req.Version, "beta") { - mode = "beta" - } - notes, err := u.loadReleaseNotes(fmt.Sprintf("%s/%s/%s/release/1panel-%s-release-notes", global.CONF.System.RepoUrl, mode, req.Version, req.Version)) - if err != nil { - return "", fmt.Errorf("load releases-notes of version %s failed, err: %v", req.Version, err) - } - return notes, nil -} - -func (u *UpgradeService) Upgrade(req dto.Upgrade) error { - global.LOG.Info("start to upgrade now...") - fileOp := files.NewFileOp() - timeStr := time.Now().Format(constant.DateTimeSlimLayout) - rootDir := path.Join(global.CONF.System.TmpDir, fmt.Sprintf("upgrade/upgrade_%s/downloads", timeStr)) - originalDir := path.Join(global.CONF.System.TmpDir, fmt.Sprintf("upgrade/upgrade_%s/original", timeStr)) - if err := os.MkdirAll(rootDir, os.ModePerm); err != nil { - return err - } - if err := os.MkdirAll(originalDir, os.ModePerm); err != nil { - return err - } - itemArch, err := loadArch() - if err != nil { - return err - } - - mode := global.CONF.System.Mode - if strings.Contains(req.Version, "beta") { - mode = "beta" - } - downloadPath := fmt.Sprintf("%s/%s/%s/release", global.CONF.System.RepoUrl, mode, req.Version) - fileName := fmt.Sprintf("1panel-%s-%s-%s.tar.gz", req.Version, "linux", itemArch) - _ = settingRepo.Update("SystemStatus", "Upgrading") - go func() { - _ = global.Cron.Stop() - defer func() { - global.Cron.Start() - }() - if err := fileOp.DownloadFileWithProxy(downloadPath+"/"+fileName, rootDir+"/"+fileName); err != nil { - global.LOG.Errorf("download service file failed, err: %v", err) - _ = settingRepo.Update("SystemStatus", "Free") - return - } - global.LOG.Info("download all file successful!") - defer func() { - _ = os.Remove(rootDir) - }() - if err := handleUnTar(rootDir+"/"+fileName, rootDir, ""); err != nil { - global.LOG.Errorf("decompress file failed, err: %v", err) - _ = settingRepo.Update("SystemStatus", "Free") - return - } - tmpDir := rootDir + "/" + strings.ReplaceAll(fileName, ".tar.gz", "") - - if err := u.handleBackup(fileOp, originalDir); err != nil { - global.LOG.Errorf("handle backup original file failed, err: %v", err) - _ = settingRepo.Update("SystemStatus", "Free") - return - } - global.LOG.Info("backup original data successful, now start to upgrade!") - - if err := common.CopyFile(path.Join(tmpDir, "1panel"), "/usr/local/bin"); err != nil { - global.LOG.Errorf("upgrade 1panel failed, err: %v", err) - u.handleRollback(originalDir, 1) - return - } - - if err := common.CopyFile(path.Join(tmpDir, "1pctl"), "/usr/local/bin"); err != nil { - global.LOG.Errorf("upgrade 1pctl failed, err: %v", err) - u.handleRollback(originalDir, 2) - return - } - if _, err := cmd.Execf("sed -i -e 's#BASE_DIR=.*#BASE_DIR=%s#g' /usr/local/bin/1pctl", global.CONF.System.BaseDir); err != nil { - global.LOG.Errorf("upgrade basedir in 1pctl failed, err: %v", err) - u.handleRollback(originalDir, 2) - return - } - - if err := common.CopyFile(path.Join(tmpDir, "1panel.service"), "/etc/systemd/system"); err != nil { - global.LOG.Errorf("upgrade 1panel.service failed, err: %v", err) - u.handleRollback(originalDir, 3) - return - } - - global.LOG.Info("upgrade successful!") - go writeLogs(req.Version) - _ = settingRepo.Update("SystemVersion", req.Version) - _ = settingRepo.Update("SystemStatus", "Free") - checkPointOfWal() - _, _ = cmd.ExecWithTimeOut("systemctl daemon-reload && systemctl restart 1panel.service", 1*time.Minute) - }() - return nil -} - -func (u *UpgradeService) handleBackup(fileOp files.FileOp, originalDir string) error { - if err := fileOp.Copy("/usr/local/bin/1panel", originalDir); err != nil { - return err - } - if err := fileOp.Copy("/usr/local/bin/1pctl", originalDir); err != nil { - return err - } - if err := fileOp.Copy("/etc/systemd/system/1panel.service", originalDir); err != nil { - return err - } - checkPointOfWal() - if err := handleTar(path.Join(global.CONF.System.BaseDir, "1panel/db"), originalDir, "db.tar.gz", "db/1Panel.db-*", ""); err != nil { - return err - } - return nil -} - -func (u *UpgradeService) handleRollback(originalDir string, errStep int) { - _ = settingRepo.Update("SystemStatus", "Free") - - checkPointOfWal() - if _, err := os.Stat(path.Join(originalDir, "1Panel.db")); err == nil { - if err := common.CopyFile(path.Join(originalDir, "1Panel.db"), global.CONF.System.DbPath); err != nil { - global.LOG.Errorf("rollback 1panel db failed, err: %v", err) - } - } - if _, err := os.Stat(path.Join(originalDir, "db.tar.gz")); err == nil { - if err := handleUnTar(path.Join(originalDir, "db.tar.gz"), global.CONF.System.DbPath, ""); err != nil { - global.LOG.Errorf("rollback 1panel db failed, err: %v", err) - } - } - if err := common.CopyFile(path.Join(originalDir, "1panel"), "/usr/local/bin"); err != nil { - global.LOG.Errorf("rollback 1pctl failed, err: %v", err) - } - if errStep == 1 { - return - } - if err := common.CopyFile(path.Join(originalDir, "1pctl"), "/usr/local/bin"); err != nil { - global.LOG.Errorf("rollback 1panel failed, err: %v", err) - } - if errStep == 2 { - return - } - if err := common.CopyFile(path.Join(originalDir, "1panel.service"), "/etc/systemd/system"); err != nil { - global.LOG.Errorf("rollback 1panel failed, err: %v", err) - } -} - -func (u *UpgradeService) loadVersionByMode(developer, currentVersion string) (string, string, string) { - var current, latest string - if global.CONF.System.Mode == "dev" { - betaVersionLatest := u.loadVersion(true, currentVersion, "beta") - devVersionLatest := u.loadVersion(true, currentVersion, "dev") - if common.ComparePanelVersion(betaVersionLatest, devVersionLatest) { - return betaVersionLatest, "", "" - } - return devVersionLatest, "", "" - } - - betaVersionLatest := "" - latest = u.loadVersion(true, currentVersion, "stable") - current = u.loadVersion(false, currentVersion, "stable") - if developer == "enable" { - betaVersionLatest = u.loadVersion(true, currentVersion, "beta") - } - if current != latest { - return betaVersionLatest, current, latest - } - - versionPart := strings.Split(current, ".") - if len(versionPart) < 3 { - return betaVersionLatest, current, latest - } - num, _ := strconv.Atoi(versionPart[1]) - if num == 0 { - return betaVersionLatest, current, latest - } - if num >= 10 { - if current[:6] == currentVersion[:6] { - return betaVersionLatest, current, "" - } - return betaVersionLatest, "", latest - } - if current[:5] == currentVersion[:5] { - return betaVersionLatest, current, "" - } - return betaVersionLatest, "", latest -} - -func (u *UpgradeService) loadVersion(isLatest bool, currentVersion, mode string) string { - path := fmt.Sprintf("%s/%s/latest", global.CONF.System.RepoUrl, mode) - if !isLatest { - path = fmt.Sprintf("%s/%s/latest.current", global.CONF.System.RepoUrl, mode) - } - _, latestVersionRes, err := httpUtil.HandleGet(path, http.MethodGet, constant.TimeOut20s) - if err != nil { - global.LOG.Errorf("load latest version from oss failed, err: %v", err) - return "" - } - version := string(latestVersionRes) - if strings.Contains(version, "<") { - global.LOG.Errorf("load latest version from oss failed, err: %v", version) - return "" - } - if isLatest { - return u.checkVersion(version, currentVersion) - } - - versionMap := make(map[string]string) - if err := json.Unmarshal(latestVersionRes, &versionMap); err != nil { - global.LOG.Errorf("load latest version from oss failed (error unmarshal), err: %v", err) - return "" - } - - versionPart := strings.Split(currentVersion, ".") - if len(versionPart) < 3 { - global.LOG.Errorf("current version is error format: %s", currentVersion) - return "" - } - num, _ := strconv.Atoi(versionPart[1]) - if num == 0 { - global.LOG.Errorf("current version is error format: %s", currentVersion) - return "" - } - if num >= 10 { - if version, ok := versionMap[currentVersion[0:5]]; ok { - return u.checkVersion(version, currentVersion) - } - return "" - } - if version, ok := versionMap[currentVersion[0:4]]; ok { - return u.checkVersion(version, currentVersion) - } - return "" -} - -func (u *UpgradeService) checkVersion(v2, v1 string) string { - addSuffix := false - if !strings.Contains(v1, "-") { - v1 = v1 + "-lts" - } - if !strings.Contains(v2, "-") { - addSuffix = true - v2 = v2 + "-lts" - } - if common.ComparePanelVersion(v2, v1) { - if addSuffix { - return strings.TrimSuffix(v2, "-lts") - } - return v2 - } - return "" -} - -func (u *UpgradeService) loadReleaseNotes(path string) (string, error) { - _, releaseNotes, err := httpUtil.HandleGet(path, http.MethodGet, constant.TimeOut20s) - if err != nil { - return "", err - } - return string(releaseNotes), nil -} - -func loadArch() (string, error) { - std, err := cmd.Exec("uname -a") - if err != nil { - return "", fmt.Errorf("std: %s, err: %s", std, err.Error()) - } - if strings.Contains(std, "x86_64") { - return "amd64", nil - } - if strings.Contains(std, "arm64") || strings.Contains(std, "aarch64") { - return "arm64", nil - } - if strings.Contains(std, "armv7l") { - return "armv7", nil - } - if strings.Contains(std, "ppc64le") { - return "ppc64le", nil - } - if strings.Contains(std, "s390x") { - return "s390x", nil - } - return "", fmt.Errorf("unsupported such arch: %s", std) -} diff --git a/backend/app/service/website.go b/backend/app/service/website.go index 48cfa9d4b..f62ababff 100644 --- a/backend/app/service/website.go +++ b/backend/app/service/website.go @@ -471,7 +471,10 @@ func (w WebsiteService) DeleteWebsite(req request.WebsiteDelete) error { tx, ctx := helper.GetTxAndContext() defer tx.Rollback() - go NewIBackupService().DeleteRecordByName("website", website.PrimaryDomain, website.Alias, req.DeleteBackup) + go func() { + _ = NewIBackupService().DeleteRecordByName("website", website.PrimaryDomain, website.Alias, req.DeleteBackup) + }() + if err := websiteRepo.DeleteBy(ctx, commonRepo.WithByID(req.ID)); err != nil { return err } diff --git a/backend/configs/system.go b/backend/configs/system.go index 2e1f1c458..d6e7c87c9 100644 --- a/backend/configs/system.go +++ b/backend/configs/system.go @@ -1,28 +1,20 @@ package configs type System struct { - Port string `mapstructure:"port"` - Ipv6 string `mapstructure:"ipv6"` - BindAddress string `mapstructure:"bindAddress"` - SSL string `mapstructure:"ssl"` - DbFile string `mapstructure:"db_file"` - DbPath string `mapstructure:"db_path"` - LogPath string `mapstructure:"log_path"` - DataDir string `mapstructure:"data_dir"` - TmpDir string `mapstructure:"tmp_dir"` - Cache string `mapstructure:"cache"` - Backup string `mapstructure:"backup"` - EncryptKey string `mapstructure:"encrypt_key"` - BaseDir string `mapstructure:"base_dir"` - Mode string `mapstructure:"mode"` - RepoUrl string `mapstructure:"repo_url"` - Version string `mapstructure:"version"` - Username string `mapstructure:"username"` - Password string `mapstructure:"password"` - Entrance string `mapstructure:"entrance"` - IsDemo bool `mapstructure:"is_demo"` - AppRepo string `mapstructure:"app_repo"` - ChangeUserInfo string `mapstructure:"change_user_info"` - OneDriveID string `mapstructure:"one_drive_id"` - OneDriveSc string `mapstructure:"one_drive_sc"` + DbFile string `mapstructure:"db_file"` + DbPath string `mapstructure:"db_path"` + LogPath string `mapstructure:"log_path"` + DataDir string `mapstructure:"data_dir"` + TmpDir string `mapstructure:"tmp_dir"` + Cache string `mapstructure:"cache"` + Backup string `mapstructure:"backup"` + EncryptKey string `mapstructure:"encrypt_key"` + BaseDir string `mapstructure:"base_dir"` + Mode string `mapstructure:"mode"` + RepoUrl string `mapstructure:"repo_url"` + Version string `mapstructure:"version"` + IsDemo bool `mapstructure:"is_demo"` + AppRepo string `mapstructure:"app_repo"` + OneDriveID string `mapstructure:"one_drive_id"` + OneDriveSc string `mapstructure:"one_drive_sc"` } diff --git a/backend/global/global.go b/backend/global/global.go index 24b660cad..cf92a8fc0 100644 --- a/backend/global/global.go +++ b/backend/global/global.go @@ -3,7 +3,6 @@ package global import ( "github.com/1Panel-dev/1Panel/backend/configs" "github.com/1Panel-dev/1Panel/backend/init/cache/badger_db" - "github.com/1Panel-dev/1Panel/backend/init/session/psession" "github.com/dgraph-io/badger/v4" "github.com/go-playground/validator/v10" "github.com/nicksnyder/go-i18n/v2/i18n" @@ -19,7 +18,6 @@ var ( LOG *logrus.Logger CONF configs.ServerConfig VALID *validator.Validate - SESSION *psession.PSession CACHE *badger_db.Cache CacheDb *badger.DB Viper *viper.Viper diff --git a/backend/init/hook/hook.go b/backend/init/hook/hook.go index 407de681e..8f02d4a79 100644 --- a/backend/init/hook/hook.go +++ b/backend/init/hook/hook.go @@ -5,40 +5,15 @@ import ( "encoding/json" "os" "path" - "strings" "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/app/repo" "github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/global" - "github.com/1Panel-dev/1Panel/backend/utils/cmd" - "github.com/1Panel-dev/1Panel/backend/utils/common" - "github.com/1Panel-dev/1Panel/backend/utils/encrypt" ) func Init() { settingRepo := repo.NewISettingRepo() - portSetting, err := settingRepo.Get(settingRepo.WithByKey("ServerPort")) - if err != nil { - global.LOG.Errorf("load service port from setting failed, err: %v", err) - } - global.CONF.System.Port = portSetting.Value - ipv6Setting, err := settingRepo.Get(settingRepo.WithByKey("Ipv6")) - if err != nil { - global.LOG.Errorf("load ipv6 status from setting failed, err: %v", err) - } - global.CONF.System.Ipv6 = ipv6Setting.Value - bindAddressSetting, err := settingRepo.Get(settingRepo.WithByKey("BindAddress")) - if err != nil { - global.LOG.Errorf("load bind address from setting failed, err: %v", err) - } - global.CONF.System.BindAddress = bindAddressSetting.Value - sslSetting, err := settingRepo.Get(settingRepo.WithByKey("SSL")) - if err != nil { - global.LOG.Errorf("load service ssl from setting failed, err: %v", err) - } - global.CONF.System.SSL = sslSetting.Value - OneDriveID, err := settingRepo.Get(settingRepo.WithByKey("OneDriveID")) if err != nil { global.LOG.Errorf("load onedrive info from setting failed, err: %v", err) @@ -59,8 +34,6 @@ func Init() { global.LOG.Fatalf("init service before start failed, err: %v", err) } - handleUserInfo(global.CONF.System.ChangeUserInfo, settingRepo) - handleCronjobStatus() handleSnapStatus() loadLocalDir() @@ -163,44 +136,6 @@ func loadLocalDir() { global.LOG.Errorf("error type dir: %T", varMap["dir"]) } -func handleUserInfo(tags string, settingRepo repo.ISettingRepo) { - if len(tags) == 0 { - return - } - if tags == "all" { - if err := settingRepo.Update("UserName", common.RandStrAndNum(10)); err != nil { - global.LOG.Fatalf("init username before start failed, err: %v", err) - } - pass, _ := encrypt.StringEncrypt(common.RandStrAndNum(10)) - if err := settingRepo.Update("Password", pass); err != nil { - global.LOG.Fatalf("init password before start failed, err: %v", err) - } - if err := settingRepo.Update("SecurityEntrance", common.RandStrAndNum(10)); err != nil { - global.LOG.Fatalf("init entrance before start failed, err: %v", err) - } - return - } - if strings.Contains(global.CONF.System.ChangeUserInfo, "username") { - if err := settingRepo.Update("UserName", common.RandStrAndNum(10)); err != nil { - global.LOG.Fatalf("init username before start failed, err: %v", err) - } - } - if strings.Contains(global.CONF.System.ChangeUserInfo, "password") { - pass, _ := encrypt.StringEncrypt(common.RandStrAndNum(10)) - if err := settingRepo.Update("Password", pass); err != nil { - global.LOG.Fatalf("init password before start failed, err: %v", err) - } - } - if strings.Contains(global.CONF.System.ChangeUserInfo, "entrance") { - if err := settingRepo.Update("SecurityEntrance", common.RandStrAndNum(10)); err != nil { - global.LOG.Fatalf("init entrance before start failed, err: %v", err) - } - } - - sudo := cmd.SudoHandleCmd() - _, _ = cmd.Execf("%s sed -i '/CHANGE_USER_INFO=%v/d' /usr/local/bin/1pctl", sudo, global.CONF.System.ChangeUserInfo) -} - func initDir() { composePath := path.Join(global.CONF.System.BaseDir, "1panel/docker/compose/") if _, err := os.Stat(composePath); err != nil && os.IsNotExist(err) { diff --git a/backend/init/migration/migrate.go b/backend/init/migration/migrate.go index 926f7f510..773f0f299 100644 --- a/backend/init/migration/migrate.go +++ b/backend/init/migration/migrate.go @@ -9,92 +9,14 @@ import ( func Init() { m := gormigrate.New(global.DB, gormigrate.DefaultOptions, []*gormigrate.Migration{ - migrations.AddTableOperationLog, - migrations.AddTableHost, - migrations.AddTableMonitor, - migrations.AddTableSetting, - migrations.AddTableBackupAccount, - migrations.AddTableCronjob, - migrations.AddTableApp, - migrations.AddTableImageRepo, - migrations.AddTableWebsite, - migrations.AddTableDatabaseMysql, - migrations.AddTableSnap, - migrations.AddDefaultGroup, - migrations.AddTableRuntime, - migrations.UpdateTableApp, - migrations.UpdateTableHost, - migrations.UpdateTableWebsite, - migrations.AddEntranceAndSSL, - migrations.UpdateTableSetting, - migrations.UpdateTableAppDetail, - migrations.AddBindAndAllowIPs, - migrations.UpdateCronjobWithSecond, - migrations.UpdateWebsite, - migrations.AddBackupAccountDir, - migrations.AddMfaInterval, - migrations.UpdateAppDetail, - migrations.EncryptHostPassword, - migrations.AddRemoteDB, - migrations.UpdateRedisParam, - migrations.UpdateCronjobWithDb, - migrations.AddTableFirewall, - migrations.AddDatabases, - migrations.UpdateDatabase, - migrations.UpdateAppInstallResource, - migrations.DropDatabaseLocal, - - migrations.AddDefaultNetwork, - migrations.UpdateRuntime, - migrations.UpdateTag, - - migrations.AddFavorite, - migrations.AddBindAddress, - migrations.AddCommandGroup, - migrations.AddAppSyncStatus, - - migrations.UpdateAcmeAccount, - migrations.UpdateWebsiteSSL, - migrations.AddWebsiteCA, - migrations.AddDockerSockPath, - migrations.AddDatabaseSSL, - migrations.AddDefaultCA, - migrations.AddSettingRecycleBin, - migrations.UpdateWebsiteBackupRecord, - - migrations.AddTablePHPExtensions, - migrations.AddTableDatabasePostgresql, - migrations.AddPostgresqlSuperUser, - migrations.UpdateCronjobWithWebsite, - migrations.UpdateOneDriveToken, - migrations.UpdateCronjobSpec, - migrations.UpdateBackupRecordPath, - migrations.UpdateSnapshotRecords, - - migrations.UpdateWebDavConf, - - migrations.AddSnapshotIgnore, - migrations.AddDatabaseIsDelete, - migrations.AddXpackHideMenu, - migrations.AddCronjobCommand, - migrations.NewMonitorDB, - migrations.AddNoAuthSetting, - migrations.UpdateXpackHideMenu, - migrations.AddMenuTabsSetting, - migrations.AddDeveloperSetting, - - migrations.AddWebsiteSSLColumn, - migrations.AddRedisCommand, - migrations.AddMonitorMenu, - migrations.AddFtp, - migrations.AddProxy, - migrations.AddCronJobColumn, - migrations.AddForward, - migrations.AddShellColumn, - migrations.AddClam, - migrations.AddClamStatus, - - migrations.AddHOSTMenu, + migrations.AddTable, + migrations.InitHost, + migrations.InitSetting, + migrations.InitBackupAccount, + migrations.InitImageRepo, + migrations.InitDefaultGroup, + migrations.InitDefaultCA, + migrations.InitPHPExtensions, }) if err := m.Migrate(); err != nil { global.LOG.Error(err) diff --git a/backend/init/migration/migrations/init.go b/backend/init/migration/migrations/init.go index 69cb1dadc..9a3d96822 100644 --- a/backend/init/migration/migrations/init.go +++ b/backend/init/migration/migrations/init.go @@ -2,41 +2,69 @@ package migrations import ( "fmt" - "strings" - "time" - - "github.com/1Panel-dev/1Panel/backend/app/service" + "github.com/1Panel-dev/1Panel/backend/app/dto/request" "github.com/1Panel-dev/1Panel/backend/app/model" - "github.com/1Panel-dev/1Panel/backend/app/repo" + "github.com/1Panel-dev/1Panel/backend/app/service" "github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/global" "github.com/1Panel-dev/1Panel/backend/utils/common" - "github.com/1Panel-dev/1Panel/backend/utils/encrypt" "github.com/go-gormigrate/gormigrate/v2" "gorm.io/gorm" ) -var AddTableOperationLog = &gormigrate.Migration{ - ID: "20200809-add-table-operation-log", +var AddTable = &gormigrate.Migration{ + ID: "20240722-add-table", Migrate: func(tx *gorm.DB) error { - return tx.AutoMigrate(&model.OperationLog{}, &model.LoginLog{}) + return tx.AutoMigrate( + &model.AppDetail{}, + &model.AppInstallResource{}, + &model.AppInstall{}, + &model.AppTag{}, + &model.Tag{}, + &model.App{}, + &model.BackupAccount{}, + &model.BackupRecord{}, + &model.Clam{}, + &model.Command{}, + &model.ComposeTemplate{}, + &model.Compose{}, + &model.Cronjob{}, + &model.Database{}, + &model.DatabaseMysql{}, + &model.DatabasePostgresql{}, + &model.Favorite{}, + &model.Forward{}, + &model.Firewall{}, + &model.Ftp{}, + &model.Group{}, + &model.Host{}, + &model.ImageRepo{}, + &model.JobRecords{}, + &model.MonitorBase{}, + &model.MonitorIO{}, + &model.MonitorNetwork{}, + &model.PHPExtensions{}, + &model.RedisCommand{}, + &model.Runtime{}, + &model.Setting{}, + &model.Snapshot{}, + &model.SnapshotStatus{}, + &model.Tag{}, + &model.Website{}, + &model.WebsiteAcmeAccount{}, + &model.WebsiteCA{}, + &model.WebsiteDnsAccount{}, + &model.WebsiteDomain{}, + &model.WebsiteSSL{}, + ) }, } -var AddTableHost = &gormigrate.Migration{ - ID: "20200818-add-table-host", +var InitHost = &gormigrate.Migration{ + ID: "20240722-init-host", Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Host{}); err != nil { - return err - } - if err := tx.AutoMigrate(&model.Group{}); err != nil { - return err - } - if err := tx.AutoMigrate(&model.Command{}); err != nil { - return err - } group := model.Group{ Name: "default", Type: "host", IsDefault: true, } @@ -53,75 +81,42 @@ var AddTableHost = &gormigrate.Migration{ }, } -var AddTableMonitor = &gormigrate.Migration{ - ID: "20200905-add-table-monitor", +var InitSetting = &gormigrate.Migration{ + ID: "20240722-init-setting", Migrate: func(tx *gorm.DB) error { - return tx.AutoMigrate(&model.MonitorBase{}, &model.MonitorIO{}, &model.MonitorNetwork{}) - }, -} - -var AddTableSetting = &gormigrate.Migration{ - ID: "20200908-add-table-setting", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Setting{}); err != nil { + if err := tx.Create(&model.Setting{Key: "SystemIP", Value: ""}).Error; err != nil { return err } - encryptKey := common.RandStr(16) - if err := tx.Create(&model.Setting{Key: "UserName", Value: global.CONF.System.Username}).Error; err != nil { + if err := tx.Create(&model.Setting{Key: "DockerSockPath", Value: "unix:///var/run/docker.sock"}).Error; err != nil { return err } - global.CONF.System.EncryptKey = encryptKey - pass, _ := encrypt.StringEncrypt(global.CONF.System.Password) - if err := tx.Create(&model.Setting{Key: "Password", Value: pass}).Error; err != nil { + if err := tx.Create(&model.Setting{Key: "SystemVersion", Value: global.CONF.System.Version}).Error; err != nil { return err } - if err := tx.Create(&model.Setting{Key: "Email", Value: ""}).Error; err != nil { + if err := tx.Create(&model.Setting{Key: "SystemStatus", Value: "Free"}).Error; err != nil { return err } - if err := tx.Create(&model.Setting{Key: "PanelName", Value: "1Panel"}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "Language", Value: "zh"}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "Theme", Value: "light"}).Error; err != nil { - return err - } - - if err := tx.Create(&model.Setting{Key: "SessionTimeout", Value: "86400"}).Error; err != nil { - return err - } if err := tx.Create(&model.Setting{Key: "LocalTime", Value: ""}).Error; err != nil { return err } - - if err := tx.Create(&model.Setting{Key: "ServerPort", Value: global.CONF.System.Port}).Error; err != nil { + if err := tx.Create(&model.Setting{Key: "TimeZone", Value: common.LoadTimeZoneByCmd()}).Error; err != nil { return err } - if err := tx.Create(&model.Setting{Key: "SecurityEntrance", Value: global.CONF.System.Entrance}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "JWTSigningKey", Value: common.RandStr(16)}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "EncryptKey", Value: encryptKey}).Error; err != nil { + if err := tx.Create(&model.Setting{Key: "NtpSite", Value: "pool.ntp.org"}).Error; err != nil { return err } - if err := tx.Create(&model.Setting{Key: "ExpirationTime", Value: time.Now().AddDate(0, 0, 10).Format(constant.DateTimeLayout)}).Error; err != nil { + if err := tx.Create(&model.Setting{Key: "DefaultNetwork", Value: "all"}).Error; err != nil { return err } - if err := tx.Create(&model.Setting{Key: "ExpirationDays", Value: "0"}).Error; err != nil { + if err := tx.Create(&model.Setting{Key: "LastCleanTime", Value: ""}).Error; err != nil { return err } - if err := tx.Create(&model.Setting{Key: "ComplexityVerification", Value: "enable"}).Error; err != nil { + if err := tx.Create(&model.Setting{Key: "LastCleanSize", Value: ""}).Error; err != nil { return err } - if err := tx.Create(&model.Setting{Key: "MFAStatus", Value: "disable"}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "MFASecret", Value: ""}).Error; err != nil { + if err := tx.Create(&model.Setting{Key: "LastCleanData", Value: ""}).Error; err != nil { return err } @@ -131,39 +126,40 @@ var AddTableSetting = &gormigrate.Migration{ if err := tx.Create(&model.Setting{Key: "MonitorStoreDays", Value: "7"}).Error; err != nil { return err } + if err := tx.Create(&model.Setting{Key: "MonitorInterval", Value: "5"}).Error; err != nil { + return err + } - if err := tx.Create(&model.Setting{Key: "MessageType", Value: "none"}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "EmailVars", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "WeChatVars", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "DingVars", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "SystemVersion", Value: global.CONF.System.Version}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "SystemStatus", Value: "Free"}).Error; err != nil { - return err - } if err := tx.Create(&model.Setting{Key: "AppStoreVersion", Value: ""}).Error; err != nil { return err } + if err := tx.Create(&model.Setting{Key: "AppStoreSyncStatus", Value: "SyncSuccess"}).Error; err != nil { + return err + } + if err := tx.Create(&model.Setting{Key: "AppStoreLastModified", Value: "0"}).Error; err != nil { + return err + } + + if err := tx.Create(&model.Setting{Key: "OneDriveID", Value: "MDEwOTM1YTktMWFhOS00ODU0LWExZGMtNmU0NWZlNjI4YzZi"}).Error; err != nil { + return err + } + if err := tx.Create(&model.Setting{Key: "OneDriveSc", Value: "akpuOFF+YkNXOU1OLWRzS1ZSRDdOcG1LT2ZRM0RLNmdvS1RkVWNGRA=="}).Error; err != nil { + return err + } + + if err := tx.Create(&model.Setting{Key: "FileRecycleBin", Value: "enable"}).Error; err != nil { + return err + } + if err := tx.Create(&model.Setting{Key: "SnapshotIgnore", Value: "*.sock"}).Error; err != nil { + return err + } return nil }, } -var AddTableBackupAccount = &gormigrate.Migration{ - ID: "20200916-add-table-backup", +var InitBackupAccount = &gormigrate.Migration{ + ID: "20240722-init-backup", Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.BackupAccount{}, &model.BackupRecord{}); err != nil { - return err - } - item := &model.BackupAccount{ Type: "LOCAL", Vars: fmt.Sprintf("{\"dir\":\"%s\"}", global.CONF.System.Backup), @@ -175,26 +171,9 @@ var AddTableBackupAccount = &gormigrate.Migration{ }, } -var AddTableCronjob = &gormigrate.Migration{ - ID: "20200921-add-table-cronjob", +var InitImageRepo = &gormigrate.Migration{ + ID: "20240722-init-imagerepo", Migrate: func(tx *gorm.DB) error { - return tx.AutoMigrate(&model.Cronjob{}, &model.JobRecords{}) - }, -} - -var AddTableApp = &gormigrate.Migration{ - ID: "20200921-add-table-app", - Migrate: func(tx *gorm.DB) error { - return tx.AutoMigrate(&model.App{}, &model.AppDetail{}, &model.Tag{}, &model.AppTag{}, &model.AppInstall{}, &model.AppInstallResource{}) - }, -} - -var AddTableImageRepo = &gormigrate.Migration{ - ID: "20201009-add-table-imagerepo", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.ImageRepo{}, &model.ComposeTemplate{}, &model.Compose{}); err != nil { - return err - } item := &model.ImageRepo{ Name: "Docker Hub", Protocol: "https", @@ -208,535 +187,63 @@ var AddTableImageRepo = &gormigrate.Migration{ }, } -var AddTableDatabaseMysql = &gormigrate.Migration{ - ID: "20201020-add-table-database_mysql", +var InitDefaultGroup = &gormigrate.Migration{ + ID: "20240722-init-default-group", Migrate: func(tx *gorm.DB) error { - return tx.AutoMigrate(&model.DatabaseMysql{}) - }, -} -var AddTableWebsite = &gormigrate.Migration{ - ID: "20201009-add-table-website", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Website{}, &model.WebsiteDomain{}, &model.WebsiteDnsAccount{}, &model.WebsiteSSL{}, &model.WebsiteAcmeAccount{}); err != nil { - return err - } - return nil - }, -} - -var AddTableSnap = &gormigrate.Migration{ - ID: "20230106-add-table-snap", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Snapshot{}); err != nil { - return err - } - return nil - }, -} - -var AddDefaultGroup = &gormigrate.Migration{ - ID: "2023022-change-default-group", - Migrate: func(tx *gorm.DB) error { - defaultGroup := &model.Group{ + websiteGroup := &model.Group{ Name: "默认", IsDefault: true, Type: "website", } - if err := tx.Create(defaultGroup).Error; err != nil { + if err := tx.Create(websiteGroup).Error; err != nil { return err } - if err := tx.Model(&model.Group{}).Where("name = ? AND type = ?", "default", "host").Update("name", "默认").Error; err != nil { - return err - } - if err := tx.Model(&model.Website{}).Where("1 = 1").Update("website_group_id", defaultGroup.ID).Error; err != nil { - return err - } - return tx.Migrator().DropTable("website_groups") - }, -} - -var AddTableRuntime = &gormigrate.Migration{ - ID: "20230406-add-table-runtime", - Migrate: func(tx *gorm.DB) error { - return tx.AutoMigrate(&model.Runtime{}) - }, -} - -var UpdateTableApp = &gormigrate.Migration{ - ID: "20230408-update-table-app", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.App{}); err != nil { + commandGroup := &model.Group{IsDefault: true, Name: "默认", Type: "command"} + if err := tx.Create(commandGroup).Error; err != nil { return err } return nil }, } -var UpdateTableHost = &gormigrate.Migration{ - ID: "20230410-update-table-host", +var InitDefaultCA = &gormigrate.Migration{ + ID: "20240722-init-default-ca", Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Host{}); err != nil { + caService := service.NewIWebsiteCAService() + if _, err := caService.Create(request.WebsiteCACreate{ + CommonName: "1Panel-CA", + Country: "CN", + KeyType: "P256", + Name: "1Panel", + Organization: "FIT2CLOUD", + OrganizationUint: "1Panel", + Province: "Beijing", + City: "Beijing", + }); err != nil { return err } return nil }, } -var UpdateTableWebsite = &gormigrate.Migration{ - ID: "20230418-update-table-website", +var InitPHPExtensions = &gormigrate.Migration{ + ID: "20240722-add-php-extensions", Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Website{}); err != nil { + if err := tx.Create(&model.PHPExtensions{Name: "默认", Extensions: "bcmath,gd,gettext,intl,pcntl,shmop,soap,sockets,sysvsem,xmlrpc,zip"}).Error; err != nil { return err } - if err := tx.Model(&model.Website{}).Where("1 = 1").Update("site_dir", "/").Error; err != nil { + if err := tx.Create(&model.PHPExtensions{Name: "WordPress", Extensions: "exif,igbinary,imagick,intl,zip,apcu,memcached,opcache,redis,bc,image,shmop,mysqli,pdo_mysql,gd"}).Error; err != nil { + return err + } + if err := tx.Create(&model.PHPExtensions{Name: "Flarum", Extensions: "curl,gd,pdo_mysql,mysqli,bz2,exif,yaf,imap"}).Error; err != nil { + return err + } + if err := tx.Create(&model.PHPExtensions{Name: "苹果CMS-V10", Extensions: "mysqli,pdo_mysql,zip,gd,redis,memcache,memcached"}).Error; err != nil { + return err + } + if err := tx.Create(&model.PHPExtensions{Name: "SeaCMS", Extensions: "mysqli,pdo_mysql,gd,curl"}).Error; err != nil { return err } return nil }, } - -var AddEntranceAndSSL = &gormigrate.Migration{ - ID: "20230414-add-entrance-and-ssl", - Migrate: func(tx *gorm.DB) error { - if err := tx.Model(&model.Setting{}). - Where("key = ? AND value = ?", "SecurityEntrance", "onepanel"). - Updates(map[string]interface{}{"value": ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "SSLType", Value: "self"}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "SSLID", Value: "0"}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "SSL", Value: "disable"}).Error; err != nil { - return err - } - return tx.AutoMigrate(&model.Website{}) - }, -} - -var UpdateTableSetting = &gormigrate.Migration{ - ID: "20200516-update-table-setting", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "AppStoreLastModified", Value: "0"}).Error; err != nil { - return err - } - return nil - }, -} - -var UpdateTableAppDetail = &gormigrate.Migration{ - ID: "20200517-update-table-app-detail", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.App{}); err != nil { - return err - } - if err := tx.AutoMigrate(&model.AppDetail{}); err != nil { - return err - } - return nil - }, -} - -var AddBindAndAllowIPs = &gormigrate.Migration{ - ID: "20230517-add-bind-and-allow", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "BindDomain", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "AllowIPs", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "TimeZone", Value: common.LoadTimeZoneByCmd()}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "NtpSite", Value: "pool.ntp.org"}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "MonitorInterval", Value: "5"}).Error; err != nil { - return err - } - return nil - }, -} - -var UpdateCronjobWithSecond = &gormigrate.Migration{ - ID: "20200524-update-table-cronjob", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Cronjob{}); err != nil { - return err - } - var jobs []model.Cronjob - if err := tx.Where("exclusion_rules != ?", "").Find(&jobs).Error; err != nil { - return err - } - for _, job := range jobs { - if strings.Contains(job.ExclusionRules, ";") { - newRules := strings.ReplaceAll(job.ExclusionRules, ";", ",") - if err := tx.Model(&model.Cronjob{}).Where("id = ?", job.ID).Update("exclusion_rules", newRules).Error; err != nil { - return err - } - } - } - return nil - }, -} - -var UpdateWebsite = &gormigrate.Migration{ - ID: "20200530-update-table-website", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Website{}); err != nil { - return err - } - return nil - }, -} - -var AddBackupAccountDir = &gormigrate.Migration{ - ID: "20200620-add-backup-dir", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.BackupAccount{}, &model.Cronjob{}); err != nil { - return err - } - return nil - }, -} - -var AddMfaInterval = &gormigrate.Migration{ - ID: "20230625-add-mfa-interval", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "MFAInterval", Value: "30"}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "SystemIP", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "OneDriveID", Value: "MDEwOTM1YTktMWFhOS00ODU0LWExZGMtNmU0NWZlNjI4YzZi"}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "OneDriveSc", Value: "akpuOFF+YkNXOU1OLWRzS1ZSRDdOcG1LT2ZRM0RLNmdvS1RkVWNGRA=="}).Error; err != nil { - return err - } - return nil - }, -} - -var UpdateAppDetail = &gormigrate.Migration{ - ID: "20230704-update-app-detail", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.AppDetail{}); err != nil { - return err - } - if err := tx.Model(&model.AppDetail{}).Where("1 = 1").Update("ignore_upgrade", "0").Error; err != nil { - return err - } - return nil - }, -} - -var EncryptHostPassword = &gormigrate.Migration{ - ID: "20230703-encrypt-host-password", - Migrate: func(tx *gorm.DB) error { - var hosts []model.Host - if err := tx.Where("1 = 1").Find(&hosts).Error; err != nil { - return err - } - - var encryptSetting model.Setting - if err := tx.Where("key = ?", "EncryptKey").Find(&encryptSetting).Error; err != nil { - return err - } - global.CONF.System.EncryptKey = encryptSetting.Value - - for _, host := range hosts { - if len(host.Password) != 0 { - pass, err := encrypt.StringEncrypt(host.Password) - if err != nil { - return err - } - if err := tx.Model(&model.Host{}).Where("id = ?", host.ID).Update("password", pass).Error; err != nil { - return err - } - } - if len(host.PrivateKey) != 0 { - key, err := encrypt.StringEncrypt(host.PrivateKey) - if err != nil { - return err - } - if err := tx.Model(&model.Host{}).Where("id = ?", host.ID).Update("private_key", key).Error; err != nil { - return err - } - } - if len(host.PassPhrase) != 0 { - pass, err := encrypt.StringEncrypt(host.PassPhrase) - if err != nil { - return err - } - if err := tx.Model(&model.Host{}).Where("id = ?", host.ID).Update("pass_phrase", pass).Error; err != nil { - return err - } - } - } - return nil - }, -} - -var AddRemoteDB = &gormigrate.Migration{ - ID: "20230724-add-remote-db", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Database{}, &model.DatabaseMysql{}); err != nil { - return err - } - installRepo := repo.NewIAppInstallRepo() - mysqlInfo, err := installRepo.LoadBaseInfo("mysql", "") - if err == nil { - if err := tx.Create(&model.Database{ - Name: "local", - Type: "mysql", - Version: mysqlInfo.Version, - From: "local", - Address: "127.0.0.1", - Username: "root", - Password: mysqlInfo.Password, - }).Error; err != nil { - return err - } - } - return nil - }, -} - -var UpdateRedisParam = &gormigrate.Migration{ - ID: "20230804-update-redis-param", - Migrate: func(tx *gorm.DB) error { - var ( - app model.App - appInstall model.AppInstall - ) - if err := tx.Where("key = ?", "redis").First(&app).Error; err != nil { - return nil - } - if err := tx.Where("app_id = ?", app.ID).First(&appInstall).Error; err != nil { - return nil - } - appInstall.Param = strings.ReplaceAll(appInstall.Param, "PANEL_DB_ROOT_PASSWORD", "PANEL_REDIS_ROOT_PASSWORD") - appInstall.DockerCompose = strings.ReplaceAll(appInstall.DockerCompose, "PANEL_DB_ROOT_PASSWORD", "PANEL_REDIS_ROOT_PASSWORD") - appInstall.Env = strings.ReplaceAll(appInstall.Env, "PANEL_DB_ROOT_PASSWORD", "PANEL_REDIS_ROOT_PASSWORD") - if err := tx.Model(&model.AppInstall{}).Where("id = ?", appInstall.ID).Updates(appInstall).Error; err != nil { - return err - } - return nil - }, -} - -var UpdateCronjobWithDb = &gormigrate.Migration{ - ID: "20230809-update-cronjob-with-db", - Migrate: func(tx *gorm.DB) error { - var cronjobs []model.Cronjob - if err := tx.Where("type = ? AND db_name != ?", "database", "all").Find(&cronjobs).Error; err != nil { - return nil - } - - for _, job := range cronjobs { - var db model.DatabaseMysql - if err := tx.Where("name = ?", job.DBName).First(&db).Error; err != nil { - continue - } - if err := tx.Model(&model.Cronjob{}). - Where("id = ?", job.ID). - Updates(map[string]interface{}{"db_name": db.ID}).Error; err != nil { - continue - } - } - return nil - }, -} - -var AddTableFirewall = &gormigrate.Migration{ - ID: "20230908-add-table-firewall", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Firewall{}, model.SnapshotStatus{}, &model.Cronjob{}); err != nil { - return err - } - _ = tx.Exec("alter table remote_dbs rename to databases;").Error - if err := tx.AutoMigrate(&model.Database{}); err != nil { - return err - } - return nil - }, -} - -var AddDatabases = &gormigrate.Migration{ - ID: "20230831-add-databases", - Migrate: func(tx *gorm.DB) error { - installRepo := repo.NewIAppInstallRepo() - _ = tx.Where("name = ? AND address = ?", "local", "127.0.0.1").Delete(&model.Database{}).Error - mysql := addDatabaseData(tx, installRepo, "mysql") - if mysql.AppInstallID != 0 { - if err := tx.Create(mysql).Error; err != nil { - return err - } - } - mariadb := addDatabaseData(tx, installRepo, "mariadb") - if mariadb.AppInstallID != 0 { - if err := tx.Create(mariadb).Error; err != nil { - return err - } - } - redis := addDatabaseData(tx, installRepo, "redis") - if redis.AppInstallID != 0 { - if err := tx.Create(redis).Error; err != nil { - return err - } - } - postgresql := addDatabaseData(tx, installRepo, "postgresql") - if postgresql.AppInstallID != 0 { - if err := tx.Create(postgresql).Error; err != nil { - return err - } - } - mongodb := addDatabaseData(tx, installRepo, "mongodb") - if mongodb.AppInstallID != 0 { - if err := tx.Create(mongodb).Error; err != nil { - return err - } - } - memcached := addDatabaseData(tx, installRepo, "memcached") - if memcached.AppInstallID != 0 { - if err := tx.Create(memcached).Error; err != nil { - return err - } - } - - return nil - }, -} - -var UpdateDatabase = &gormigrate.Migration{ - ID: "20230831-update-database", - Migrate: func(tx *gorm.DB) error { - if err := tx.Model(&model.DatabaseMysql{}).Where("`from` != ?", "local").Updates(map[string]interface{}{ - "from": "remote", - }).Error; err != nil { - return err - } - - var datas []model.Database - if err := tx.Find(&datas).Error; err != nil { - return nil - } - for _, data := range datas { - pass, err := encrypt.StringEncrypt(data.Password) - if err != nil { - global.LOG.Errorf("encrypt database %s password failed, err: %v", data.Name, err) - continue - } - if err := tx.Model(&model.Database{}).Where("id = ?", data.ID).Updates(map[string]interface{}{ - "password": pass, - }).Error; err != nil { - global.LOG.Errorf("updata database %s info failed, err: %v", data.Name, err) - } - } - - var mysqls []model.DatabaseMysql - if err := tx.Find(&mysqls).Error; err != nil { - return nil - } - for _, data := range mysqls { - pass, err := encrypt.StringEncrypt(data.Password) - if err != nil { - global.LOG.Errorf("encrypt database db %s password failed, err: %v", data.Name, err) - continue - } - if err := tx.Model(&model.DatabaseMysql{}).Where("id = ?", data.ID).Updates(map[string]interface{}{ - "password": pass, - }).Error; err != nil { - global.LOG.Errorf("updata database db %s info failed, err: %v", data.Name, err) - } - } - return nil - }, -} - -var UpdateAppInstallResource = &gormigrate.Migration{ - ID: "20230831-update-app_install_resource", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.AppInstallResource{}); err != nil { - return err - } - if err := tx.Model(&model.AppInstallResource{}).Where("1 = 1").Updates(map[string]interface{}{ - "from": "local", - }).Error; err != nil { - return err - } - return nil - }, -} - -var DropDatabaseLocal = &gormigrate.Migration{ - ID: "20230914-drop-database-local", - Migrate: func(tx *gorm.DB) error { - _ = tx.Where("name = ? AND address = ?", "local", "127.0.0.1").Delete(&model.Database{}).Error - return nil - }, -} - -func addDatabaseData(tx *gorm.DB, installRepo repo.IAppInstallRepo, appType string) *model.Database { - dbInfo, err := installRepo.LoadBaseInfo(appType, "") - if err != nil { - return &model.Database{} - } - - if appType == "mysql" || appType == "redis" || appType == "mariadb" || appType == "memcached" { - dbInfo.UserName = "root" - } - database := &model.Database{ - AppInstallID: dbInfo.ID, - Name: dbInfo.Name, - Type: appType, - Version: dbInfo.Version, - From: "local", - Address: dbInfo.ServiceName, - Port: service.DatabaseKeys[appType], - Username: dbInfo.UserName, - Password: dbInfo.Password, - } - var dbItem model.Database - _ = global.DB.Where("name = ?", dbInfo.Name).First(&dbItem).Error - if dbItem.ID != 0 { - if appType == "mysql" { - var ( - backups []model.BackupRecord - mysqls []model.DatabaseMysql - ) - _ = tx.Where("name = ? AND type = ?", dbItem.Name, "mysql").Find(&backups) - _ = tx.Where("`from` = ?", "local").Find(&mysqls) - for _, item := range backups { - isLocal := false - for _, mysql := range mysqls { - if item.Name == mysql.MysqlName && item.DetailName == mysql.Name { - isLocal = true - break - } - } - if !isLocal { - _ = tx.Model(&model.BackupRecord{}).Where("id = ?", item.ID).Updates(map[string]interface{}{ - "name": "remote-" + dbItem.Name, - }).Error - } - } - } - if err := tx.Debug().Model(&model.DatabaseMysql{}).Where("mysql_name = ? AND `from` != ?", dbItem.Name, "local").Updates(map[string]interface{}{ - "mysql_name": "remote-" + dbItem.Name, - }).Error; err != nil { - fmt.Println(err) - } - if err := tx.Debug().Model(&model.Database{}).Where("name = ?", dbItem.Name).Updates(map[string]interface{}{ - "name": "remote-" + dbItem.Name, - }).Error; err != nil { - fmt.Println(err) - } - } - return database -} diff --git a/backend/init/migration/migrations/v_1_10.go b/backend/init/migration/migrations/v_1_10.go deleted file mode 100644 index e0ac6be2f..000000000 --- a/backend/init/migration/migrations/v_1_10.go +++ /dev/null @@ -1,316 +0,0 @@ -package migrations - -import ( - "encoding/json" - - "github.com/1Panel-dev/1Panel/backend/app/dto" - "github.com/1Panel-dev/1Panel/backend/app/model" - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/go-gormigrate/gormigrate/v2" - "gorm.io/gorm" -) - -var AddSnapshotIgnore = &gormigrate.Migration{ - ID: "20240311-add-snapshot-ignore", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "SnapshotIgnore", Value: "*.sock"}).Error; err != nil { - return err - } - return nil - }, -} - -var AddDatabaseIsDelete = &gormigrate.Migration{ - ID: "20240314-add-database-is-delete", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.DatabaseMysql{}, &model.DatabasePostgresql{}); err != nil { - return err - } - return nil - }, -} - -var AddXpackHideMenu = &gormigrate.Migration{ - ID: "20240328-add-xpack-hide-menu", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "XpackHideMenu", Value: "{\"id\":\"1\",\"label\":\"/xpack\",\"isCheck\":true,\"title\":\"xpack.menu\",\"children\":[{\"id\":\"2\",\"title\":\"xpack.waf.name\",\"path\":\"/xpack/waf/dashboard\",\"label\":\"Dashboard\",\"isCheck\":true},{\"id\":\"3\",\"title\":\"xpack.tamper.tamper\",\"path\":\"/xpack/tamper\",\"label\":\"Tamper\",\"isCheck\":true},{\"id\":\"4\",\"title\":\"xpack.setting.setting\",\"path\":\"/xpack/setting\",\"label\":\"XSetting\",\"isCheck\":true}]}"}).Error; err != nil { - return err - } - return nil - }, -} - -var AddCronjobCommand = &gormigrate.Migration{ - ID: "20240403-add-cronjob-command", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Cronjob{}); err != nil { - return err - } - return nil - }, -} - -var NewMonitorDB = &gormigrate.Migration{ - ID: "20240408-new-monitor-db", - Migrate: func(tx *gorm.DB) error { - var ( - bases []model.MonitorBase - ios []model.MonitorIO - networks []model.MonitorNetwork - ) - _ = tx.Find(&bases).Error - _ = tx.Find(&ios).Error - _ = tx.Find(&networks).Error - - if err := global.MonitorDB.AutoMigrate(&model.MonitorBase{}, &model.MonitorIO{}, &model.MonitorNetwork{}); err != nil { - return err - } - _ = global.MonitorDB.Exec("DELETE FROM monitor_bases").Error - _ = global.MonitorDB.Exec("DELETE FROM monitor_ios").Error - _ = global.MonitorDB.Exec("DELETE FROM monitor_networks").Error - - if len(bases) != 0 { - for i := 0; i <= len(bases)/200; i++ { - var itemData []model.MonitorBase - if 200*(i+1) <= len(bases) { - itemData = bases[200*i : 200*(i+1)] - } else { - itemData = bases[200*i:] - } - if len(itemData) != 0 { - if err := global.MonitorDB.Create(&itemData).Error; err != nil { - return err - } - } - } - } - if len(ios) != 0 { - for i := 0; i <= len(ios)/200; i++ { - var itemData []model.MonitorIO - if 200*(i+1) <= len(ios) { - itemData = ios[200*i : 200*(i+1)] - } else { - itemData = ios[200*i:] - } - if len(itemData) != 0 { - if err := global.MonitorDB.Create(&itemData).Error; err != nil { - return err - } - } - } - } - if len(networks) != 0 { - for i := 0; i <= len(networks)/200; i++ { - var itemData []model.MonitorNetwork - if 200*(i+1) <= len(networks) { - itemData = networks[200*i : 200*(i+1)] - } else { - itemData = networks[200*i:] - } - if len(itemData) != 0 { - if err := global.MonitorDB.Create(&itemData).Error; err != nil { - return err - } - } - } - } - return nil - }, -} - -var AddNoAuthSetting = &gormigrate.Migration{ - ID: "20240328-add-no-auth-setting", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "NoAuthSetting", Value: "200"}).Error; err != nil { - return err - } - return nil - }, -} - -var UpdateXpackHideMenu = &gormigrate.Migration{ - ID: "20240411-update-xpack-hide-menu", - Migrate: func(tx *gorm.DB) error { - if err := tx.Model(&model.Setting{}).Where("key", "XpackHideMenu").Updates(map[string]interface{}{"value": "{\"id\":\"1\",\"label\":\"/xpack\",\"isCheck\":true,\"title\":\"xpack.menu\",\"children\":[{\"id\":\"2\",\"title\":\"xpack.waf.name\",\"path\":\"/xpack/waf/dashboard\",\"label\":\"Dashboard\",\"isCheck\":true},{\"id\":\"3\",\"title\":\"xpack.tamper.tamper\",\"path\":\"/xpack/tamper\",\"label\":\"Tamper\",\"isCheck\":true},{\"id\":\"4\",\"title\":\"xpack.gpu.gpu\",\"path\":\"/xpack/gpu\",\"label\":\"GPU\",\"isCheck\":true},{\"id\":\"5\",\"title\":\"xpack.setting.setting\",\"path\":\"/xpack/setting\",\"label\":\"XSetting\",\"isCheck\":true}]}"}).Error; err != nil { - return err - } - return nil - }, -} - -var AddMenuTabsSetting = &gormigrate.Migration{ - ID: "20240415-add-menu-tabs-setting", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "MenuTabs", Value: "disable"}).Error; err != nil { - return err - } - return nil - }, -} - -var AddDeveloperSetting = &gormigrate.Migration{ - ID: "20240423-add-developer-setting", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "DeveloperMode", Value: "disable"}).Error; err != nil { - return err - } - return nil - }, -} - -var AddWebsiteSSLColumn = &gormigrate.Migration{ - ID: "20240508-update-website-ssl", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.WebsiteSSL{}); err != nil { - return err - } - return nil - }, -} - -var AddRedisCommand = &gormigrate.Migration{ - ID: "20240515-add-redis-command", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.RedisCommand{}); err != nil { - return err - } - return nil - }, -} - -var AddMonitorMenu = &gormigrate.Migration{ - ID: "20240517-update-xpack-hide-menu", - Migrate: func(tx *gorm.DB) error { - var ( - setting model.Setting - menu dto.XpackHideMenu - ) - tx.Model(&model.Setting{}).Where("key", "XpackHideMenu").First(&setting) - if err := json.Unmarshal([]byte(setting.Value), &menu); err != nil { - return err - } - menu.Children = append(menu.Children, dto.XpackHideMenu{ - ID: "6", - Title: "xpack.monitor.name", - Path: "/xpack/monitor/dashboard", - Label: "MonitorDashboard", - IsCheck: true, - }) - data, err := json.Marshal(menu) - if err != nil { - return err - } - return tx.Model(&model.Setting{}).Where("key", "XpackHideMenu").Updates(map[string]interface{}{"value": string(data)}).Error - }, -} - -var AddFtp = &gormigrate.Migration{ - ID: "20240521-add-ftp", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Ftp{}, model.Website{}); err != nil { - return err - } - return nil - }, -} - -var AddProxy = &gormigrate.Migration{ - ID: "20240528-add-proxy", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "ProxyType", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "ProxyUrl", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "ProxyPort", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "ProxyUser", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "ProxyPasswd", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "ProxyPasswdKeep", Value: ""}).Error; err != nil { - return err - } - return nil - }, -} - -var AddForward = &gormigrate.Migration{ - ID: "202400611-add-forward", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Forward{}); err != nil { - return err - } - return nil - }, -} - -var AddCronJobColumn = &gormigrate.Migration{ - ID: "20240524-add-cronjob-command", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Cronjob{}); err != nil { - return err - } - return nil - }, -} - -var AddShellColumn = &gormigrate.Migration{ - ID: "20240620-update-website-ssl", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.WebsiteSSL{}); err != nil { - return err - } - return nil - }, -} - -var AddClam = &gormigrate.Migration{ - ID: "20240701-add-clam", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Clam{}); err != nil { - return err - } - return nil - }, -} - -var AddClamStatus = &gormigrate.Migration{ - ID: "20240716-add-clam-status", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Clam{}); err != nil { - return err - } - return nil - }, -} - -var AddHOSTMenu = &gormigrate.Migration{ - ID: "20240722-add-xpack-host-menu", - Migrate: func(tx *gorm.DB) error { - var ( - setting model.Setting - menu dto.XpackHideMenu - ) - tx.Model(&model.Setting{}).Where("key", "XpackHideMenu").First(&setting) - if err := json.Unmarshal([]byte(setting.Value), &menu); err != nil { - return err - } - menu.Children = append(menu.Children, dto.XpackHideMenu{ - ID: "7", - Title: "多主机", - Path: "/xpack/multihost/manage", - Label: "Multihost", - IsCheck: true, - }) - data, err := json.Marshal(menu) - if err != nil { - return err - } - return tx.Model(&model.Setting{}).Where("key", "XpackHideMenu").Updates(map[string]interface{}{"value": string(data)}).Error - }, -} diff --git a/backend/init/migration/migrations/v_1_7.go b/backend/init/migration/migrations/v_1_7.go deleted file mode 100644 index d8d621a27..000000000 --- a/backend/init/migration/migrations/v_1_7.go +++ /dev/null @@ -1,46 +0,0 @@ -package migrations - -import ( - "github.com/1Panel-dev/1Panel/backend/app/model" - "github.com/go-gormigrate/gormigrate/v2" - "gorm.io/gorm" -) - -var AddDefaultNetwork = &gormigrate.Migration{ - ID: "20230928-add-default-network", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "DefaultNetwork", Value: "all"}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "LastCleanTime", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "LastCleanSize", Value: ""}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "LastCleanData", Value: ""}).Error; err != nil { - return err - } - return nil - }, -} - -var UpdateRuntime = &gormigrate.Migration{ - ID: "20230927-update-runtime", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Runtime{}); err != nil { - return err - } - return nil - }, -} - -var UpdateTag = &gormigrate.Migration{ - ID: "20231008-update-tag", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Tag{}); err != nil { - return err - } - return nil - }, -} diff --git a/backend/init/migration/migrations/v_1_8.go b/backend/init/migration/migrations/v_1_8.go deleted file mode 100644 index b47fc91c2..000000000 --- a/backend/init/migration/migrations/v_1_8.go +++ /dev/null @@ -1,57 +0,0 @@ -package migrations - -import ( - "github.com/1Panel-dev/1Panel/backend/app/model" - "github.com/go-gormigrate/gormigrate/v2" - "gorm.io/gorm" -) - -var AddFavorite = &gormigrate.Migration{ - ID: "20231020-add-favorite", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Favorite{}); err != nil { - return err - } - return nil - }, -} - -var AddBindAddress = &gormigrate.Migration{ - ID: "20231024-add-bind-address", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "BindAddress", Value: "0.0.0.0"}).Error; err != nil { - return err - } - if err := tx.Create(&model.Setting{Key: "Ipv6", Value: "disable"}).Error; err != nil { - return err - } - return nil - }, -} - -var AddCommandGroup = &gormigrate.Migration{ - ID: "20231030-add-command-group", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Command{}); err != nil { - return err - } - defaultCommand := &model.Group{IsDefault: true, Name: "默认", Type: "command"} - if err := tx.Create(defaultCommand).Error; err != nil { - return err - } - if err := tx.Model(&model.Command{}).Where("1 = 1").Update("group_id", defaultCommand.ID).Error; err != nil { - return err - } - return nil - }, -} - -var AddAppSyncStatus = &gormigrate.Migration{ - ID: "20231103-update-table-setting", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "AppStoreSyncStatus", Value: "SyncSuccess"}).Error; err != nil { - return err - } - return nil - }, -} diff --git a/backend/init/migration/migrations/v_1_9.go b/backend/init/migration/migrations/v_1_9.go deleted file mode 100644 index fcf5ca71b..000000000 --- a/backend/init/migration/migrations/v_1_9.go +++ /dev/null @@ -1,490 +0,0 @@ -package migrations - -import ( - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "path" - "strings" - "time" - - "github.com/1Panel-dev/1Panel/backend/app/dto/request" - "github.com/1Panel-dev/1Panel/backend/app/model" - "github.com/1Panel-dev/1Panel/backend/app/repo" - "github.com/1Panel-dev/1Panel/backend/app/service" - "github.com/1Panel-dev/1Panel/backend/constant" - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/1Panel-dev/1Panel/backend/utils/cloud_storage/client" - "github.com/go-gormigrate/gormigrate/v2" - "gorm.io/gorm" -) - -var UpdateAcmeAccount = &gormigrate.Migration{ - ID: "20231117-update-acme-account", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.WebsiteAcmeAccount{}); err != nil { - return err - } - return nil - }, -} - -var AddWebsiteCA = &gormigrate.Migration{ - ID: "20231125-add-website-ca", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.WebsiteCA{}); err != nil { - return err - } - return nil - }, -} - -var UpdateWebsiteSSL = &gormigrate.Migration{ - ID: "20231128-update-website-ssl", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.WebsiteSSL{}); err != nil { - return err - } - return nil - }, -} - -var AddDockerSockPath = &gormigrate.Migration{ - ID: "20231128-add-docker-sock-path", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "DockerSockPath", Value: "unix:///var/run/docker.sock"}).Error; err != nil { - return err - } - return nil - }, -} - -var AddDatabaseSSL = &gormigrate.Migration{ - ID: "20231126-add-database-ssl", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Database{}); err != nil { - return err - } - return nil - }, -} - -var AddDefaultCA = &gormigrate.Migration{ - ID: "20231129-add-default-ca", - Migrate: func(tx *gorm.DB) error { - caService := service.NewIWebsiteCAService() - if _, err := caService.Create(request.WebsiteCACreate{ - CommonName: "1Panel-CA", - Country: "CN", - KeyType: "P256", - Name: "1Panel", - Organization: "FIT2CLOUD", - OrganizationUint: "1Panel", - Province: "Beijing", - City: "Beijing", - }); err != nil { - return err - } - return nil - }, -} - -var AddSettingRecycleBin = &gormigrate.Migration{ - ID: "20231129-add-setting-recycle-bin", - Migrate: func(tx *gorm.DB) error { - if err := tx.Create(&model.Setting{Key: "FileRecycleBin", Value: "enable"}).Error; err != nil { - return err - } - return nil - }, -} - -var UpdateWebsiteBackupRecord = &gormigrate.Migration{ - ID: "20231218-update-backup-record-for-website", - Migrate: func(tx *gorm.DB) error { - backupRepo := repo.NewIBackupRepo() - websitesBackups, _ := backupRepo.ListRecord(repo.NewCommonRepo().WithByType("website")) - if len(websitesBackups) > 0 { - for _, backup := range websitesBackups { - backup.DetailName = backup.Name - _ = backupRepo.UpdateRecord(&backup) - } - } - return nil - }, -} - -var AddTablePHPExtensions = &gormigrate.Migration{ - ID: "20240102-add-php-extensions", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.PHPExtensions{}); err != nil { - return err - } - if err := tx.Create(&model.PHPExtensions{Name: "默认", Extensions: "bcmath,gd,gettext,intl,pcntl,shmop,soap,sockets,sysvsem,xmlrpc,zip"}).Error; err != nil { - return err - } - if err := tx.Create(&model.PHPExtensions{Name: "WordPress", Extensions: "exif,igbinary,imagick,intl,zip,apcu,memcached,opcache,redis,bc,image,shmop,mysqli,pdo_mysql,gd"}).Error; err != nil { - return err - } - if err := tx.Create(&model.PHPExtensions{Name: "Flarum", Extensions: "curl,gd,pdo_mysql,mysqli,bz2,exif,yaf,imap"}).Error; err != nil { - return err - } - if err := tx.Create(&model.PHPExtensions{Name: "苹果CMS-V10", Extensions: "mysqli,pdo_mysql,zip,gd,redis,memcache,memcached"}).Error; err != nil { - return err - } - if err := tx.Create(&model.PHPExtensions{Name: "SeaCMS", Extensions: "mysqli,pdo_mysql,gd,curl"}).Error; err != nil { - return err - } - return nil - }, -} - -var AddTableDatabasePostgresql = &gormigrate.Migration{ - ID: "20231225-add-table-database_postgresql", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.DatabasePostgresql{}); err != nil { - return err - } - if err := tx.AutoMigrate(&model.Cronjob{}); err != nil { - return err - } - var jobs []model.Cronjob - if err := tx.Where("type == ?", "database").Find(&jobs).Error; err != nil { - return err - } - for _, job := range jobs { - if job.DBName == "all" { - if err := tx.Model(&model.Cronjob{}).Where("id = ?", job.ID).Update("db_type", "mysql").Error; err != nil { - global.LOG.Errorf("update db type of cronjob %s failed, err: %v", job.Name, err) - continue - } - } - var db model.DatabaseMysql - if err := tx.Where("id == ?", job.DBName).First(&db).Error; err != nil { - continue - } - var database model.Database - if err := tx.Where("name == ?", db.MysqlName).First(&database).Error; err != nil { - continue - } - if err := tx.Model(&model.Cronjob{}).Where("id = ?", job.ID).Update("db_type", database.Type).Error; err != nil { - global.LOG.Errorf("update db type of cronjob %s failed, err: %v", job.Name, err) - continue - } - } - return nil - }, -} - -var AddPostgresqlSuperUser = &gormigrate.Migration{ - ID: "20231225-add-postgresql-super_user", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.DatabasePostgresql{}); err != nil { - return err - } - return nil - }, -} - -var UpdateCronjobWithWebsite = &gormigrate.Migration{ - ID: "20230809-update-cronjob-with-website", - Migrate: func(tx *gorm.DB) error { - var cronjobs []model.Cronjob - if err := tx.Where("(type = ? OR type = ?) AND website != ?", "website", "cutWebsiteLog", "all").Find(&cronjobs).Error; err != nil { - return err - } - - for _, job := range cronjobs { - var web model.Website - if err := tx.Where("primary_domain = ?", job.Website).First(&web).Error; err != nil { - continue - } - if err := tx.Model(&model.Cronjob{}). - Where("id = ?", job.ID). - Updates(map[string]interface{}{"website": web.ID}).Error; err != nil { - continue - } - } - - return nil - }, -} - -var UpdateOneDriveToken = &gormigrate.Migration{ - ID: "20240117-update-onedrive-token", - Migrate: func(tx *gorm.DB) error { - var ( - backup model.BackupAccount - clientSetting model.Setting - secretSetting model.Setting - ) - _ = tx.Where("type = ?", "OneDrive").First(&backup).Error - if backup.ID == 0 { - return nil - } - if len(backup.Credential) == 0 { - global.LOG.Error("OneDrive configuration lacks token information, please rebind.") - return nil - } - - _ = tx.Where("key = ?", "OneDriveID").First(&clientSetting).Error - if clientSetting.ID == 0 { - global.LOG.Error("system configuration lacks clientID information, please retry.") - return nil - } - _ = tx.Where("key = ?", "OneDriveSc").First(&secretSetting).Error - if secretSetting.ID == 0 { - global.LOG.Error("system configuration lacks clientID information, please retry.") - return nil - } - idItem, _ := base64.StdEncoding.DecodeString(clientSetting.Value) - global.CONF.System.OneDriveID = string(idItem) - scItem, _ := base64.StdEncoding.DecodeString(secretSetting.Value) - global.CONF.System.OneDriveSc = string(scItem) - - varMap := make(map[string]interface{}) - varMap["isCN"] = false - varMap["client_id"] = global.CONF.System.OneDriveID - varMap["client_secret"] = global.CONF.System.OneDriveSc - varMap["redirect_uri"] = constant.OneDriveRedirectURI - varMap["refresh_token"] = backup.Credential - refreshToken, err := client.RefreshToken("refresh_token", "refreshToken", varMap) - varMap["refresh_status"] = constant.StatusSuccess - varMap["refresh_time"] = time.Now().Format(constant.DateTimeLayout) - if err != nil { - varMap["refresh_msg"] = err.Error() - varMap["refresh_status"] = constant.StatusFailed - } - varMap["refresh_token"] = refreshToken - itemVars, _ := json.Marshal(varMap) - if err := tx.Model(&model.BackupAccount{}). - Where("id = ?", backup.ID). - Updates(map[string]interface{}{ - "vars": string(itemVars), - }).Error; err != nil { - return err - } - - return nil - }, -} - -var UpdateCronjobSpec = &gormigrate.Migration{ - ID: "20240122-update-cronjob-spec", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Cronjob{}); err != nil { - return err - } - if err := tx.AutoMigrate(&model.BackupRecord{}); err != nil { - return err - } - var ( - jobs []model.Cronjob - backupAccounts []model.BackupAccount - ) - mapAccount := make(map[uint]model.BackupAccount) - if err := tx.Find(&jobs).Error; err != nil { - return err - } - _ = tx.Find(&backupAccounts).Error - for _, item := range backupAccounts { - mapAccount[item.ID] = item - } - for _, job := range jobs { - if job.KeepLocal && mapAccount[uint(job.TargetDirID)].Type != constant.Local { - if err := tx.Model(&model.Cronjob{}). - Where("id = ?", job.ID). - Updates(map[string]interface{}{ - "backup_accounts": fmt.Sprintf("%v,%v", mapAccount[uint(job.TargetDirID)].Type, constant.Local), - "default_download": constant.Local, - }).Error; err != nil { - return err - } - job.DefaultDownload = constant.Local - } else { - if err := tx.Model(&model.Cronjob{}). - Where("id = ?", job.ID). - Updates(map[string]interface{}{ - "backup_accounts": mapAccount[uint(job.TargetDirID)].Type, - "default_download": mapAccount[uint(job.TargetDirID)].Type, - }).Error; err != nil { - return err - } - job.DefaultDownload = mapAccount[uint(job.TargetDirID)].Type - } - if job.Type != "directory" && job.Type != "database" && job.Type != "website" && job.Type != "app" && job.Type != "snapshot" && job.Type != "log" { - continue - } - - itemPath := mapAccount[uint(job.TargetDirID)].BackupPath - if job.DefaultDownload == constant.Local || itemPath == "/" { - itemPath = "" - } else { - itemPath = strings.TrimPrefix(itemPath, "/") + "/" - } - - var records []model.JobRecords - _ = tx.Where("cronjob_id = ?", job.ID).Find(&records).Error - for _, record := range records { - if job.Type == "snapshot" && record.Status == constant.StatusSuccess { - var snaps []model.Snapshot - _ = tx.Where("name like ?", "snapshot_"+"%").Find(&snaps).Error - for _, snap := range snaps { - item := model.BackupRecord{ - From: "cronjob", - CronjobID: job.ID, - Type: "snapshot", - Name: job.Name, - FileDir: "system_snapshot", - FileName: snap.Name + ".tar.gz", - Source: snap.From, - BackupType: snap.From, - BaseModel: model.BaseModel{ - CreatedAt: record.CreatedAt, - }, - } - _ = tx.Create(&item).Error - } - continue - } - if job.Type == "log" && record.Status == constant.StatusSuccess { - item := model.BackupRecord{ - From: "cronjob", - CronjobID: job.ID, - Type: "log", - Name: job.Name, - FileDir: path.Dir(strings.TrimPrefix(record.File, itemPath)), - FileName: path.Base(record.File), - Source: mapAccount[uint(job.TargetDirID)].Type, - BackupType: mapAccount[uint(job.TargetDirID)].Type, - BaseModel: model.BaseModel{ - CreatedAt: record.CreatedAt, - }, - } - _ = tx.Create(&item).Error - continue - } - if job.Type == "directory" && record.Status == constant.StatusSuccess { - item := model.BackupRecord{ - From: "cronjob", - CronjobID: job.ID, - Type: "directory", - Name: job.Name, - FileDir: path.Dir(strings.TrimPrefix(record.File, itemPath)), - FileName: path.Base(record.File), - BackupType: mapAccount[uint(job.TargetDirID)].Type, - BaseModel: model.BaseModel{ - CreatedAt: record.CreatedAt, - }, - } - if record.FromLocal { - item.Source = constant.Local - } else { - item.Source = mapAccount[uint(job.TargetDirID)].Type - } - _ = tx.Create(&item).Error - continue - } - if strings.Contains(record.File, ",") { - files := strings.Split(record.File, ",") - for _, file := range files { - _ = tx.Model(&model.BackupRecord{}). - Where("file_dir = ? AND file_name = ?", path.Dir(strings.TrimPrefix(file, itemPath)), path.Base(file)). - Updates(map[string]interface{}{"cronjob_id": job.ID, "from": "cronjob"}).Error - } - } else { - _ = tx.Model(&model.BackupRecord{}). - Where("file_dir = ? AND file_name = ?", path.Dir(strings.TrimPrefix(record.File, itemPath)), path.Base(record.File)). - Updates(map[string]interface{}{"cronjob_id": job.ID, "from": "cronjob"}).Error - } - } - } - - _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN spec_type;").Error - _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN week;").Error - _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN day;").Error - _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN hour;").Error - _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN minute;").Error - _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN second;").Error - _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN entry_id;").Error - - return nil - }, -} - -var UpdateBackupRecordPath = &gormigrate.Migration{ - ID: "20240124-update-cronjob-spec", - Migrate: func(tx *gorm.DB) error { - var ( - backupRecords []model.BackupRecord - localAccount model.BackupAccount - ) - - _ = tx.Where("type = ?", "LOCAL").First(&localAccount).Error - if localAccount.ID == 0 { - return nil - } - varMap := make(map[string]string) - if err := json.Unmarshal([]byte(localAccount.Vars), &varMap); err != nil { - return err - } - dir, ok := varMap["dir"] - if !ok { - return errors.New("load local backup dir failed") - } - if dir != "/" { - dir += "/" - } - _ = tx.Where("source = ?", "LOCAL").Find(&backupRecords).Error - for _, record := range backupRecords { - _ = tx.Model(&model.BackupRecord{}). - Where("id = ?", record.ID). - Updates(map[string]interface{}{"file_dir": strings.TrimPrefix(record.FileDir, dir)}).Error - } - return nil - }, -} - -var UpdateSnapshotRecords = &gormigrate.Migration{ - ID: "20240124-update-snapshot-records", - Migrate: func(tx *gorm.DB) error { - if err := tx.AutoMigrate(&model.Snapshot{}); err != nil { - return err - } - var snaps []model.Snapshot - _ = tx.Find(&snaps).Error - for _, snap := range snaps { - _ = tx.Model(&model.Snapshot{}). - Where("id = ?", snap.ID). - Updates(map[string]interface{}{"default_download": snap.From}).Error - } - return nil - }, -} - -var UpdateWebDavConf = &gormigrate.Migration{ - ID: "20240205-update-webdav-conf", - Migrate: func(tx *gorm.DB) error { - var backup model.BackupAccount - _ = tx.Where("type = ?", constant.WebDAV).First(&backup).Error - if backup.ID == 0 { - return nil - } - varMap := make(map[string]interface{}) - if err := json.Unmarshal([]byte(backup.Vars), &varMap); err != nil { - return err - } - delete(varMap, "addressItem") - if port, ok := varMap["port"]; ok { - varMap["address"] = fmt.Sprintf("%s:%v", varMap["address"], port) - delete(varMap, "port") - } - - vars, _ := json.Marshal(varMap) - if err := tx.Model(&model.BackupAccount{}).Where("id = ?", backup.ID).Updates(map[string]interface{}{"vars": string(vars)}).Error; err != nil { - return err - } - return nil - }, -} diff --git a/backend/init/router/router.go b/backend/init/router/router.go index 214cfcc6a..217e65be0 100644 --- a/backend/init/router/router.go +++ b/backend/init/router/router.go @@ -1,19 +1,11 @@ package router import ( - "fmt" - "net/http" - - "github.com/1Panel-dev/1Panel/backend/global" "github.com/1Panel-dev/1Panel/backend/i18n" "github.com/1Panel-dev/1Panel/backend/middleware" rou "github.com/1Panel-dev/1Panel/backend/router" - "github.com/1Panel-dev/1Panel/cmd/server/docs" - "github.com/1Panel-dev/1Panel/cmd/server/web" "github.com/gin-contrib/gzip" "github.com/gin-gonic/gin" - swaggerfiles "github.com/swaggo/files" - ginSwagger "github.com/swaggo/gin-swagger" ) var ( @@ -21,43 +13,16 @@ var ( ) func setWebStatic(rootRouter *gin.RouterGroup) { - rootRouter.StaticFS("/public", http.FS(web.Favicon)) rootRouter.Static("/api/v1/images", "./uploads") rootRouter.Use(func(c *gin.Context) { c.Next() }) - rootRouter.GET("/assets/*filepath", func(c *gin.Context) { - c.Writer.Header().Set("Cache-Control", fmt.Sprintf("private, max-age=%d", 3600)) - staticServer := http.FileServer(http.FS(web.Assets)) - staticServer.ServeHTTP(c.Writer, c.Request) - }) - rootRouter.GET("/", func(c *gin.Context) { - staticServer := http.FileServer(http.FS(web.IndexHtml)) - staticServer.ServeHTTP(c.Writer, c.Request) - }) } func Routers() *gin.Engine { Router = gin.Default() - Router.Use(middleware.OperationLog()) - // Router.Use(middleware.CSRF()) - // Router.Use(middleware.LoadCsrfToken()) - if global.CONF.System.IsDemo { - Router.Use(middleware.DemoHandle()) - } - - Router.NoRoute(func(c *gin.Context) { - c.Writer.WriteHeader(http.StatusOK) - _, _ = c.Writer.Write(web.IndexByte) - c.Writer.Header().Add("Accept", "text/html") - c.Writer.Flush() - }) - Router.Use(i18n.UseI18n()) - swaggerRouter := Router.Group("1panel") - docs.SwaggerInfo.BasePath = "/api/v1" - swaggerRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler)) PublicGroup := Router.Group("") { PublicGroup.GET("/health", func(c *gin.Context) { @@ -67,8 +32,6 @@ func Routers() *gin.Engine { setWebStatic(PublicGroup) } PrivateGroup := Router.Group("/api/v1") - PrivateGroup.Use(middleware.WhiteAllow()) - PrivateGroup.Use(middleware.BindDomain()) PrivateGroup.Use(middleware.GlobalLoading()) for _, router := range rou.RouterGroupApp { router.InitRouter(PrivateGroup) diff --git a/backend/init/session/psession/psession.go b/backend/init/session/psession/psession.go deleted file mode 100644 index 90cff7d5e..000000000 --- a/backend/init/session/psession/psession.go +++ /dev/null @@ -1,47 +0,0 @@ -package psession - -import ( - "encoding/json" - "time" - - "github.com/1Panel-dev/1Panel/backend/init/cache/badger_db" -) - -type SessionUser struct { - ID uint `json:"id"` - Name string `json:"name"` -} - -type PSession struct { - ExpireTime int64 `json:"expire_time"` - store *badger_db.Cache -} - -func NewPSession(db *badger_db.Cache) *PSession { - return &PSession{ - store: db, - } -} - -func (p *PSession) Get(sessionID string) (SessionUser, error) { - var result SessionUser - item, err := p.store.Get(sessionID) - if err != nil { - return result, err - } - _ = json.Unmarshal(item, &result) - return result, nil -} - -func (p *PSession) Set(sessionID string, user SessionUser, ttlSeconds int) error { - p.ExpireTime = time.Now().Unix() + int64(ttlSeconds) - return p.store.SetWithTTL(sessionID, user, time.Second*time.Duration(ttlSeconds)) -} - -func (p *PSession) Delete(sessionID string) error { - return p.store.Del(sessionID) -} - -func (p *PSession) Clean() error { - return p.store.Clean() -} diff --git a/backend/init/session/session.go b/backend/init/session/session.go deleted file mode 100644 index 0eba926e9..000000000 --- a/backend/init/session/session.go +++ /dev/null @@ -1,11 +0,0 @@ -package session - -import ( - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/1Panel-dev/1Panel/backend/init/session/psession" -) - -func Init() { - global.SESSION = psession.NewPSession(global.CACHE) - global.LOG.Info("init session successfully") -} diff --git a/backend/init/viper/viper.go b/backend/init/viper/viper.go index 7cae3824b..084a7d84d 100644 --- a/backend/init/viper/viper.go +++ b/backend/init/viper/viper.go @@ -18,10 +18,8 @@ import ( func Init() { baseDir := "/opt" - port := "9999" mode := "" version := "v1.0.0" - username, password, entrance := "", "", "" fileOp := files.NewFileOp() v := viper.NewWithOptions() v.SetConfigType("yaml") @@ -41,11 +39,7 @@ func Init() { } } else { baseDir = loadParams("BASE_DIR") - port = loadParams("ORIGINAL_PORT") version = loadParams("ORIGINAL_VERSION") - username = loadParams("ORIGINAL_USERNAME") - password = loadParams("ORIGINAL_PASSWORD") - entrance = loadParams("ORIGINAL_ENTRANCE") reader := bytes.NewReader(conf.AppYaml) if err := v.ReadConfig(reader); err != nil { @@ -65,21 +59,9 @@ func Init() { if serverConfig.System.BaseDir != "" { baseDir = serverConfig.System.BaseDir } - if serverConfig.System.Port != "" { - port = serverConfig.System.Port - } if serverConfig.System.Version != "" { version = serverConfig.System.Version } - if serverConfig.System.Username != "" { - username = serverConfig.System.Username - } - if serverConfig.System.Password != "" { - password = serverConfig.System.Password - } - if serverConfig.System.Entrance != "" { - entrance = serverConfig.System.Entrance - } } global.CONF = serverConfig @@ -91,12 +73,7 @@ func Init() { global.CONF.System.DbPath = path.Join(global.CONF.System.DataDir, "db") global.CONF.System.LogPath = path.Join(global.CONF.System.DataDir, "log") global.CONF.System.TmpDir = path.Join(global.CONF.System.DataDir, "tmp") - global.CONF.System.Port = port global.CONF.System.Version = version - global.CONF.System.Username = username - global.CONF.System.Password = password - global.CONF.System.Entrance = entrance - global.CONF.System.ChangeUserInfo = loadChangeInfo() global.Viper = v } @@ -111,11 +88,3 @@ func loadParams(param string) string { } return info } - -func loadChangeInfo() string { - stdout, err := cmd.Exec("grep '^CHANGE_USER_INFO=' /usr/local/bin/1pctl | cut -d'=' -f2") - if err != nil { - return "" - } - return strings.ReplaceAll(stdout, "\n", "") -} diff --git a/backend/middleware/bind_domain.go b/backend/middleware/bind_domain.go deleted file mode 100644 index 1b561cbe6..000000000 --- a/backend/middleware/bind_domain.go +++ /dev/null @@ -1,41 +0,0 @@ -package middleware - -import ( - "errors" - "strings" - - "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" - "github.com/1Panel-dev/1Panel/backend/app/repo" - "github.com/1Panel-dev/1Panel/backend/constant" - "github.com/gin-gonic/gin" -) - -func BindDomain() gin.HandlerFunc { - return func(c *gin.Context) { - settingRepo := repo.NewISettingRepo() - status, err := settingRepo.Get(settingRepo.WithByKey("BindDomain")) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - if len(status.Value) == 0 { - c.Next() - return - } - domains := c.Request.Host - parts := strings.Split(c.Request.Host, ":") - if len(parts) > 0 { - domains = parts[0] - } - - if domains != status.Value { - if LoadErrCode("err-domain") != 200 { - helper.ErrResponse(c, LoadErrCode("err-domain")) - return - } - helper.ErrorWithDetail(c, constant.CodeErrDomain, constant.ErrTypeInternalServer, errors.New("domain not allowed")) - return - } - c.Next() - } -} diff --git a/backend/middleware/ip_limit.go b/backend/middleware/ip_limit.go deleted file mode 100644 index 9bef2b80a..000000000 --- a/backend/middleware/ip_limit.go +++ /dev/null @@ -1,67 +0,0 @@ -package middleware - -import ( - "errors" - "net" - "strings" - - "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" - "github.com/1Panel-dev/1Panel/backend/app/repo" - "github.com/1Panel-dev/1Panel/backend/constant" - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/gin-gonic/gin" -) - -func WhiteAllow() gin.HandlerFunc { - return func(c *gin.Context) { - settingRepo := repo.NewISettingRepo() - status, err := settingRepo.Get(settingRepo.WithByKey("AllowIPs")) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - if len(status.Value) == 0 { - c.Next() - return - } - clientIP := c.ClientIP() - for _, ip := range strings.Split(status.Value, ",") { - if len(ip) == 0 { - continue - } - if ip == clientIP || (strings.Contains(ip, "/") && checkIpInCidr(ip, clientIP)) { - c.Next() - return - } - } - if LoadErrCode("err-ip") != 200 { - helper.ErrResponse(c, LoadErrCode("err-ip")) - return - } - helper.ErrorWithDetail(c, constant.CodeErrIP, constant.ErrTypeInternalServer, errors.New("IP address not allowed")) - } -} - -func checkIpInCidr(cidr, checkIP string) bool { - ip, ipNet, err := net.ParseCIDR(cidr) - if err != nil { - global.LOG.Errorf("parse CIDR %s failed, err: %v", cidr, err) - return false - } - for ip := ip.Mask(ipNet.Mask); ipNet.Contains(ip); incIP(ip) { - if ip.String() == checkIP { - return true - } - } - return false -} - -func incIP(ip net.IP) { - for j := len(ip) - 1; j >= 0; j-- { - ip[j]++ - if ip[j] > 0 { - break - } - } -} diff --git a/backend/middleware/jwt.go b/backend/middleware/jwt.go deleted file mode 100644 index 8adb851d9..000000000 --- a/backend/middleware/jwt.go +++ /dev/null @@ -1,28 +0,0 @@ -package middleware - -import ( - "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" - "github.com/1Panel-dev/1Panel/backend/constant" - jwtUtils "github.com/1Panel-dev/1Panel/backend/utils/jwt" - - "github.com/gin-gonic/gin" -) - -func JwtAuth() gin.HandlerFunc { - return func(c *gin.Context) { - token := c.Request.Header.Get(constant.JWTHeaderName) - if token == "" { - c.Next() - return - } - j := jwtUtils.NewJWT() - claims, err := j.ParseToken(token) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrUnauthorized, constant.ErrTypeInternalServer, err) - return - } - c.Set("claims", claims) - c.Set("authMethod", constant.AuthMethodJWT) - c.Next() - } -} diff --git a/backend/middleware/operation.go b/backend/middleware/operation.go deleted file mode 100644 index d6b695e06..000000000 --- a/backend/middleware/operation.go +++ /dev/null @@ -1,216 +0,0 @@ -package middleware - -import ( - "bytes" - "compress/gzip" - "encoding/json" - "fmt" - "io" - "net/http" - "strings" - "time" - - "github.com/1Panel-dev/1Panel/backend/app/model" - "github.com/1Panel-dev/1Panel/backend/app/service" - "github.com/1Panel-dev/1Panel/backend/constant" - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/1Panel-dev/1Panel/backend/utils/copier" - "github.com/1Panel-dev/1Panel/cmd/server/docs" - "github.com/gin-gonic/gin" -) - -func OperationLog() gin.HandlerFunc { - return func(c *gin.Context) { - if strings.Contains(c.Request.URL.Path, "search") || c.Request.Method == http.MethodGet { - c.Next() - return - } - - source := loadLogInfo(c.Request.URL.Path) - record := model.OperationLog{ - Source: source, - IP: c.ClientIP(), - Method: strings.ToLower(c.Request.Method), - Path: strings.ReplaceAll(c.Request.URL.Path, "/api/v1", ""), - UserAgent: c.Request.UserAgent(), - } - var ( - swagger swaggerJson - operationDic operationJson - ) - if err := json.Unmarshal(docs.SwaggerJson, &swagger); err != nil { - c.Next() - return - } - path, hasPath := swagger.Paths[record.Path] - if !hasPath { - c.Next() - return - } - methodMap, isMethodMap := path.(map[string]interface{}) - if !isMethodMap { - c.Next() - return - } - dataMap, hasPost := methodMap["post"] - if !hasPost { - c.Next() - return - } - data, isDataMap := dataMap.(map[string]interface{}) - if !isDataMap { - c.Next() - return - } - xlog, hasXlog := data["x-panel-log"] - if !hasXlog { - c.Next() - return - } - if err := copier.Copy(&operationDic, xlog); err != nil { - c.Next() - return - } - if len(operationDic.FormatZH) == 0 { - c.Next() - return - } - - formatMap := make(map[string]interface{}) - if len(operationDic.BodyKeys) != 0 { - body, err := io.ReadAll(c.Request.Body) - if err == nil { - c.Request.Body = io.NopCloser(bytes.NewBuffer(body)) - } - bodyMap := make(map[string]interface{}) - _ = json.Unmarshal(body, &bodyMap) - for _, key := range operationDic.BodyKeys { - if _, ok := bodyMap[key]; ok { - formatMap[key] = bodyMap[key] - } - } - } - if len(operationDic.BeforeFunctions) != 0 { - for _, funcs := range operationDic.BeforeFunctions { - for key, value := range formatMap { - if funcs.InputValue == key { - var names []string - if funcs.IsList { - sql := fmt.Sprintf("SELECT %s FROM %s where %s in (?);", funcs.OutputColumn, funcs.DB, funcs.InputColumn) - _ = global.DB.Raw(sql, value).Scan(&names) - } else { - _ = global.DB.Raw(fmt.Sprintf("select %s from %s where %s = ?;", funcs.OutputColumn, funcs.DB, funcs.InputColumn), value).Scan(&names) - } - formatMap[funcs.OutputValue] = strings.Join(names, ",") - break - } - } - } - } - for key, value := range formatMap { - if strings.Contains(operationDic.FormatEN, "["+key+"]") { - if arrays, ok := value.([]string); ok { - operationDic.FormatZH = strings.ReplaceAll(operationDic.FormatZH, "["+key+"]", fmt.Sprintf("[%v]", strings.Join(arrays, ","))) - operationDic.FormatEN = strings.ReplaceAll(operationDic.FormatEN, "["+key+"]", fmt.Sprintf("[%v]", strings.Join(arrays, ","))) - } else { - operationDic.FormatZH = strings.ReplaceAll(operationDic.FormatZH, "["+key+"]", fmt.Sprintf("[%v]", value)) - operationDic.FormatEN = strings.ReplaceAll(operationDic.FormatEN, "["+key+"]", fmt.Sprintf("[%v]", value)) - } - } - } - record.DetailEN = strings.ReplaceAll(operationDic.FormatEN, "[]", "") - record.DetailZH = strings.ReplaceAll(operationDic.FormatZH, "[]", "") - - writer := responseBodyWriter{ - ResponseWriter: c.Writer, - body: &bytes.Buffer{}, - } - c.Writer = writer - now := time.Now() - - c.Next() - - datas := writer.body.Bytes() - if c.Request.Header.Get("Content-Encoding") == "gzip" { - buf := bytes.NewReader(writer.body.Bytes()) - reader, err := gzip.NewReader(buf) - if err != nil { - record.Status = constant.StatusFailed - record.Message = fmt.Sprintf("gzip new reader failed, err: %v", err) - latency := time.Since(now) - record.Latency = latency - - if err := service.NewILogService().CreateOperationLog(record); err != nil { - global.LOG.Errorf("create operation record failed, err: %v", err) - } - return - } - defer reader.Close() - datas, _ = io.ReadAll(reader) - } - var res response - _ = json.Unmarshal(datas, &res) - if res.Code == 200 { - record.Status = constant.StatusSuccess - } else { - record.Status = constant.StatusFailed - record.Message = res.Message - } - - latency := time.Since(now) - record.Latency = latency - - if err := service.NewILogService().CreateOperationLog(record); err != nil { - global.LOG.Errorf("create operation record failed, err: %v", err) - } - } -} - -type swaggerJson struct { - Paths map[string]interface{} `json:"paths"` -} - -type operationJson struct { - API string `json:"api"` - Method string `json:"method"` - BodyKeys []string `json:"bodyKeys"` - ParamKeys []string `json:"paramKeys"` - BeforeFunctions []functionInfo `json:"beforeFunctions"` - FormatZH string `json:"formatZH"` - FormatEN string `json:"formatEN"` -} -type functionInfo struct { - InputColumn string `json:"input_column"` - InputValue string `json:"input_value"` - IsList bool `json:"isList"` - DB string `json:"db"` - OutputColumn string `json:"output_column"` - OutputValue string `json:"output_value"` -} - -type response struct { - Code int `json:"code"` - Message string `json:"message"` -} - -type responseBodyWriter struct { - gin.ResponseWriter - body *bytes.Buffer -} - -func (r responseBodyWriter) Write(b []byte) (int, error) { - r.body.Write(b) - return r.ResponseWriter.Write(b) -} - -func loadLogInfo(path string) string { - path = strings.ReplaceAll(path, "/api/v1", "") - if !strings.Contains(path, "/") { - return "" - } - pathArrays := strings.Split(path, "/") - if len(pathArrays) < 2 { - return "" - } - return pathArrays[1] -} diff --git a/backend/middleware/password_expired.go b/backend/middleware/password_expired.go deleted file mode 100644 index d917f43f1..000000000 --- a/backend/middleware/password_expired.go +++ /dev/null @@ -1,45 +0,0 @@ -package middleware - -import ( - "strconv" - "time" - - "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" - "github.com/1Panel-dev/1Panel/backend/app/repo" - "github.com/1Panel-dev/1Panel/backend/constant" - "github.com/1Panel-dev/1Panel/backend/utils/common" - "github.com/gin-gonic/gin" -) - -func PasswordExpired() gin.HandlerFunc { - return func(c *gin.Context) { - settingRepo := repo.NewISettingRepo() - setting, err := settingRepo.Get(settingRepo.WithByKey("ExpirationDays")) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypePasswordExpired, err) - return - } - expiredDays, _ := strconv.Atoi(setting.Value) - if expiredDays == 0 { - c.Next() - return - } - - extime, err := settingRepo.Get(settingRepo.WithByKey("ExpirationTime")) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypePasswordExpired, err) - return - } - loc, _ := time.LoadLocation(common.LoadTimeZone()) - expiredTime, err := time.ParseInLocation(constant.DateTimeLayout, extime.Value, loc) - if err != nil { - helper.ErrorWithDetail(c, constant.CodePasswordExpired, constant.ErrTypePasswordExpired, err) - return - } - if time.Now().After(expiredTime) { - helper.ErrorWithDetail(c, constant.CodePasswordExpired, constant.ErrTypePasswordExpired, err) - return - } - c.Next() - } -} diff --git a/backend/middleware/session.go b/backend/middleware/session.go deleted file mode 100644 index 5bffb1cb9..000000000 --- a/backend/middleware/session.go +++ /dev/null @@ -1,38 +0,0 @@ -package middleware - -import ( - "strconv" - - "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" - "github.com/1Panel-dev/1Panel/backend/app/repo" - "github.com/1Panel-dev/1Panel/backend/constant" - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/gin-gonic/gin" -) - -func SessionAuth() gin.HandlerFunc { - return func(c *gin.Context) { - if method, exist := c.Get("authMethod"); exist && method == constant.AuthMethodJWT { - c.Next() - return - } - sId, err := c.Cookie(constant.SessionName) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrUnauthorized, constant.ErrTypeNotLogin, nil) - return - } - psession, err := global.SESSION.Get(sId) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrUnauthorized, constant.ErrTypeNotLogin, nil) - return - } - settingRepo := repo.NewISettingRepo() - setting, err := settingRepo.Get(settingRepo.WithByKey("SessionTimeout")) - if err != nil { - global.LOG.Errorf("create operation record failed, err: %v", err) - } - lifeTime, _ := strconv.Atoi(setting.Value) - _ = global.SESSION.Set(sId, psession, lifeTime) - c.Next() - } -} diff --git a/backend/router/common.go b/backend/router/common.go index 245598738..b96153767 100644 --- a/backend/router/common.go +++ b/backend/router/common.go @@ -2,7 +2,6 @@ package router func commonGroups() []CommonRouter { return []CommonRouter{ - &BaseRouter{}, &DashboardRouter{}, &HostRouter{}, &ContainerRouter{}, diff --git a/backend/router/ro_app.go b/backend/router/ro_app.go index 70bc790d3..12877f54c 100644 --- a/backend/router/ro_app.go +++ b/backend/router/ro_app.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -11,7 +10,6 @@ type AppRouter struct { func (a *AppRouter) InitRouter(Router *gin.RouterGroup) { appRouter := Router.Group("apps") - appRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { diff --git a/backend/router/ro_base.go b/backend/router/ro_base.go deleted file mode 100644 index 0ea3808b1..000000000 --- a/backend/router/ro_base.go +++ /dev/null @@ -1,22 +0,0 @@ -package router - -import ( - v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/gin-gonic/gin" -) - -type BaseRouter struct{} - -func (s *BaseRouter) InitRouter(Router *gin.RouterGroup) { - baseRouter := Router.Group("auth") - baseApi := v1.ApiGroupApp.BaseApi - { - baseRouter.GET("/captcha", baseApi.Captcha) - baseRouter.POST("/mfalogin", baseApi.MFALogin) - baseRouter.POST("/login", baseApi.Login) - baseRouter.GET("/issafety", baseApi.CheckIsSafety) - baseRouter.POST("/logout", baseApi.LogOut) - baseRouter.GET("/demo", baseApi.CheckIsDemo) - baseRouter.GET("/language", baseApi.GetLanguage) - } -} diff --git a/backend/router/ro_container.go b/backend/router/ro_container.go index 7764bda90..33e591851 100644 --- a/backend/router/ro_container.go +++ b/backend/router/ro_container.go @@ -2,17 +2,13 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) type ContainerRouter struct{} func (s *ContainerRouter) InitRouter(Router *gin.RouterGroup) { - baRouter := Router.Group("containers"). - Use(middleware.JwtAuth()). - Use(middleware.SessionAuth()). - Use(middleware.PasswordExpired()) + baRouter := Router.Group("containers") baseApi := v1.ApiGroupApp.BaseApi { baRouter.GET("/exec", baseApi.ContainerWsSsh) diff --git a/backend/router/ro_cronjob.go b/backend/router/ro_cronjob.go index 745662793..672ff36a5 100644 --- a/backend/router/ro_cronjob.go +++ b/backend/router/ro_cronjob.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -10,10 +9,7 @@ import ( type CronjobRouter struct{} func (s *CronjobRouter) InitRouter(Router *gin.RouterGroup) { - cmdRouter := Router.Group("cronjobs"). - Use(middleware.JwtAuth()). - Use(middleware.SessionAuth()). - Use(middleware.PasswordExpired()) + cmdRouter := Router.Group("cronjobs") baseApi := v1.ApiGroupApp.BaseApi { cmdRouter.POST("", baseApi.CreateCronjob) diff --git a/backend/router/ro_dashboard.go b/backend/router/ro_dashboard.go index 7a4109b32..1445e6180 100644 --- a/backend/router/ro_dashboard.go +++ b/backend/router/ro_dashboard.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -10,10 +9,7 @@ import ( type DashboardRouter struct{} func (s *DashboardRouter) InitRouter(Router *gin.RouterGroup) { - cmdRouter := Router.Group("dashboard"). - Use(middleware.JwtAuth()). - Use(middleware.SessionAuth()). - Use(middleware.PasswordExpired()) + cmdRouter := Router.Group("dashboard") baseApi := v1.ApiGroupApp.BaseApi { cmdRouter.GET("/base/os", baseApi.LoadDashboardOsInfo) diff --git a/backend/router/ro_database.go b/backend/router/ro_database.go index c0307651d..e2dd4e016 100644 --- a/backend/router/ro_database.go +++ b/backend/router/ro_database.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -10,10 +9,7 @@ import ( type DatabaseRouter struct{} func (s *DatabaseRouter) InitRouter(Router *gin.RouterGroup) { - cmdRouter := Router.Group("databases"). - Use(middleware.JwtAuth()). - Use(middleware.SessionAuth()). - Use(middleware.PasswordExpired()) + cmdRouter := Router.Group("databases") baseApi := v1.ApiGroupApp.BaseApi { cmdRouter.POST("/common/info", baseApi.LoadDBBaseInfo) diff --git a/backend/router/ro_file.go b/backend/router/ro_file.go index a70307aaf..78fba28ce 100644 --- a/backend/router/ro_file.go +++ b/backend/router/ro_file.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -11,7 +10,6 @@ type FileRouter struct { func (f *FileRouter) InitRouter(Router *gin.RouterGroup) { fileRouter := Router.Group("files") - fileRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { fileRouter.POST("/search", baseApi.ListFiles) diff --git a/backend/router/ro_group.go b/backend/router/ro_group.go index 33c18f35b..aefcdee40 100644 --- a/backend/router/ro_group.go +++ b/backend/router/ro_group.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -11,7 +10,6 @@ type WebsiteGroupRouter struct { func (a *WebsiteGroupRouter) InitRouter(Router *gin.RouterGroup) { groupRouter := Router.Group("groups") - groupRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { diff --git a/backend/router/ro_host.go b/backend/router/ro_host.go index c35abfd62..1405b2014 100644 --- a/backend/router/ro_host.go +++ b/backend/router/ro_host.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -10,10 +9,7 @@ import ( type HostRouter struct{} func (s *HostRouter) InitRouter(Router *gin.RouterGroup) { - hostRouter := Router.Group("hosts"). - Use(middleware.JwtAuth()). - Use(middleware.SessionAuth()). - Use(middleware.PasswordExpired()) + hostRouter := Router.Group("hosts") baseApi := v1.ApiGroupApp.BaseApi { hostRouter.POST("", baseApi.CreateHost) diff --git a/backend/router/ro_log.go b/backend/router/ro_log.go index 0ca10024e..1bb372ad7 100644 --- a/backend/router/ro_log.go +++ b/backend/router/ro_log.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -11,12 +10,8 @@ type LogRouter struct{} func (s *LogRouter) InitRouter(Router *gin.RouterGroup) { operationRouter := Router.Group("logs") - operationRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { - operationRouter.POST("/login", baseApi.GetLoginLogs) - operationRouter.POST("/operation", baseApi.GetOperationLogs) - operationRouter.POST("/clean", baseApi.CleanLogs) operationRouter.GET("/system/files", baseApi.GetSystemFiles) operationRouter.POST("/system", baseApi.GetSystemLogs) } diff --git a/backend/router/ro_nginx.go b/backend/router/ro_nginx.go index b483c8995..38bf3825a 100644 --- a/backend/router/ro_nginx.go +++ b/backend/router/ro_nginx.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -11,7 +10,6 @@ type NginxRouter struct { func (a *NginxRouter) InitRouter(Router *gin.RouterGroup) { groupRouter := Router.Group("openresty") - groupRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { diff --git a/backend/router/ro_process.go b/backend/router/ro_process.go index 1e99c6748..d077ff8ae 100644 --- a/backend/router/ro_process.go +++ b/backend/router/ro_process.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -11,7 +10,6 @@ type ProcessRouter struct { func (f *ProcessRouter) InitRouter(Router *gin.RouterGroup) { processRouter := Router.Group("process") - processRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { processRouter.GET("/ws", baseApi.ProcessWs) diff --git a/backend/router/ro_runtime.go b/backend/router/ro_runtime.go index eeee73c45..6e35b89ff 100644 --- a/backend/router/ro_runtime.go +++ b/backend/router/ro_runtime.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -11,7 +10,6 @@ type RuntimeRouter struct { func (r *RuntimeRouter) InitRouter(Router *gin.RouterGroup) { groupRouter := Router.Group("runtimes") - groupRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { diff --git a/backend/router/ro_setting.go b/backend/router/ro_setting.go index e2a911e0a..dcb3c1eab 100644 --- a/backend/router/ro_setting.go +++ b/backend/router/ro_setting.go @@ -2,37 +2,18 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) type SettingRouter struct{} func (s *SettingRouter) InitRouter(Router *gin.RouterGroup) { - router := Router.Group("settings"). - Use(middleware.JwtAuth()). - Use(middleware.SessionAuth()) - settingRouter := Router.Group("settings"). - Use(middleware.JwtAuth()). - Use(middleware.SessionAuth()). - Use(middleware.PasswordExpired()) + settingRouter := Router.Group("settings") baseApi := v1.ApiGroupApp.BaseApi { - router.POST("/search", baseApi.GetSettingInfo) - router.POST("/expired/handle", baseApi.HandlePasswordExpired) + settingRouter.POST("/search", baseApi.GetSettingInfo) settingRouter.GET("/search/available", baseApi.GetSystemAvailable) settingRouter.POST("/update", baseApi.UpdateSetting) - settingRouter.GET("/interface", baseApi.LoadInterfaceAddr) - settingRouter.POST("/menu/update", baseApi.UpdateMenu) - settingRouter.POST("/proxy/update", baseApi.UpdateProxy) - settingRouter.POST("/bind/update", baseApi.UpdateBindInfo) - settingRouter.POST("/port/update", baseApi.UpdatePort) - settingRouter.POST("/ssl/update", baseApi.UpdateSSL) - settingRouter.GET("/ssl/info", baseApi.LoadFromCert) - settingRouter.POST("/ssl/download", baseApi.DownloadSSL) - settingRouter.POST("/password/update", baseApi.UpdatePassword) - settingRouter.POST("/mfa", baseApi.LoadMFA) - settingRouter.POST("/mfa/bind", baseApi.MFABind) settingRouter.POST("/snapshot", baseApi.CreateSnapshot) settingRouter.POST("/snapshot/status", baseApi.LoadSnapShotStatus) @@ -59,9 +40,6 @@ func (s *SettingRouter) InitRouter(Router *gin.RouterGroup) { settingRouter.POST("/backup/record/download", baseApi.DownloadRecord) settingRouter.POST("/backup/record/del", baseApi.DeleteBackupRecord) - settingRouter.POST("/upgrade", baseApi.Upgrade) - settingRouter.POST("/upgrade/notes", baseApi.GetNotesByVersion) - settingRouter.GET("/upgrade", baseApi.GetUpgradeInfo) settingRouter.GET("/basedir", baseApi.LoadBaseDir) } } diff --git a/backend/router/ro_terminal.go b/backend/router/ro_terminal.go index 40c3850b3..d263c70e4 100644 --- a/backend/router/ro_terminal.go +++ b/backend/router/ro_terminal.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -10,10 +9,7 @@ import ( type TerminalRouter struct{} func (s *TerminalRouter) InitRouter(Router *gin.RouterGroup) { - terminalRouter := Router.Group("terminals"). - Use(middleware.JwtAuth()). - Use(middleware.SessionAuth()). - Use(middleware.PasswordExpired()) + terminalRouter := Router.Group("terminals") baseApi := v1.ApiGroupApp.BaseApi { terminalRouter.GET("", baseApi.WsSsh) diff --git a/backend/router/ro_toolbox.go b/backend/router/ro_toolbox.go index 6a331bbb2..8487d43dd 100644 --- a/backend/router/ro_toolbox.go +++ b/backend/router/ro_toolbox.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -10,10 +9,7 @@ import ( type ToolboxRouter struct{} func (s *ToolboxRouter) InitRouter(Router *gin.RouterGroup) { - toolboxRouter := Router.Group("toolbox"). - Use(middleware.JwtAuth()). - Use(middleware.SessionAuth()). - Use(middleware.PasswordExpired()) + toolboxRouter := Router.Group("toolbox") baseApi := v1.ApiGroupApp.BaseApi { toolboxRouter.POST("/device/base", baseApi.LoadDeviceBaseInfo) diff --git a/backend/router/ro_website.go b/backend/router/ro_website.go index 7931c8003..0c91907b2 100644 --- a/backend/router/ro_website.go +++ b/backend/router/ro_website.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -11,7 +10,6 @@ type WebsiteRouter struct { func (a *WebsiteRouter) InitRouter(Router *gin.RouterGroup) { websiteRouter := Router.Group("websites") - websiteRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { diff --git a/backend/router/ro_website_acme_account.go b/backend/router/ro_website_acme_account.go index 787957423..f620d32d8 100644 --- a/backend/router/ro_website_acme_account.go +++ b/backend/router/ro_website_acme_account.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -11,7 +10,6 @@ type WebsiteAcmeAccountRouter struct { func (a *WebsiteAcmeAccountRouter) InitRouter(Router *gin.RouterGroup) { groupRouter := Router.Group("websites/acme") - groupRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { diff --git a/backend/router/ro_website_ca.go b/backend/router/ro_website_ca.go index 9701a569d..5fbcc9f9c 100644 --- a/backend/router/ro_website_ca.go +++ b/backend/router/ro_website_ca.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -11,7 +10,6 @@ type WebsiteCARouter struct { func (a *WebsiteCARouter) InitRouter(Router *gin.RouterGroup) { groupRouter := Router.Group("websites/ca") - groupRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { diff --git a/backend/router/ro_website_dns_account.go b/backend/router/ro_website_dns_account.go index 6b46f9aa4..8416df5c2 100644 --- a/backend/router/ro_website_dns_account.go +++ b/backend/router/ro_website_dns_account.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -11,7 +10,6 @@ type WebsiteDnsAccountRouter struct { func (a *WebsiteDnsAccountRouter) InitRouter(Router *gin.RouterGroup) { groupRouter := Router.Group("websites/dns") - groupRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { diff --git a/backend/router/ro_website_ssl.go b/backend/router/ro_website_ssl.go index e0deb8701..5664d39e0 100644 --- a/backend/router/ro_website_ssl.go +++ b/backend/router/ro_website_ssl.go @@ -2,7 +2,6 @@ package router import ( v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1" - "github.com/1Panel-dev/1Panel/backend/middleware" "github.com/gin-gonic/gin" ) @@ -11,7 +10,6 @@ type WebsiteSSLRouter struct { func (a *WebsiteSSLRouter) InitRouter(Router *gin.RouterGroup) { groupRouter := Router.Group("websites/ssl") - groupRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { diff --git a/backend/server/server.go b/backend/server/server.go index a8d468690..0464acc9c 100644 --- a/backend/server/server.go +++ b/backend/server/server.go @@ -1,13 +1,8 @@ package server import ( - "crypto/tls" - "encoding/gob" - "fmt" "net" "net/http" - "os" - "path" "github.com/1Panel-dev/1Panel/backend/i18n" @@ -15,9 +10,6 @@ import ( "github.com/1Panel-dev/1Panel/backend/init/business" "github.com/1Panel-dev/1Panel/backend/cron" - "github.com/1Panel-dev/1Panel/backend/init/cache" - "github.com/1Panel-dev/1Panel/backend/init/session" - "github.com/1Panel-dev/1Panel/backend/init/session/psession" "github.com/1Panel-dev/1Panel/backend/global" "github.com/1Panel-dev/1Panel/backend/init/db" @@ -39,9 +31,6 @@ func Start() { migration.Init() app.Init() validator.Init() - gob.Register(psession.SessionUser{}) - cache.Init() - session.Init() gin.SetMode("debug") cron.Run() InitOthers() @@ -50,49 +39,20 @@ func Start() { rootRouter := router.Routers() - tcpItem := "tcp4" - if global.CONF.System.Ipv6 == "enable" { - tcpItem = "tcp" - global.CONF.System.BindAddress = fmt.Sprintf("[%s]", global.CONF.System.BindAddress) - } server := &http.Server{ - Addr: global.CONF.System.BindAddress + ":" + global.CONF.System.Port, + Addr: ":9999", Handler: rootRouter, } - ln, err := net.Listen(tcpItem, server.Addr) + ln, err := net.Listen("tcp4", ":9999") if err != nil { panic(err) } type tcpKeepAliveListener struct { *net.TCPListener } - if global.CONF.System.SSL == "enable" { - certPath := path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt") - keyPath := path.Join(global.CONF.System.BaseDir, "1panel/secret/server.key") - certificate, err := os.ReadFile(certPath) - if err != nil { - panic(err) - } - key, err := os.ReadFile(keyPath) - if err != nil { - panic(err) - } - cert, err := tls.X509KeyPair(certificate, key) - if err != nil { - panic(err) - } - server.TLSConfig = &tls.Config{ - Certificates: []tls.Certificate{cert}, - } - global.LOG.Infof("listen at https://%s:%s [%s]", global.CONF.System.BindAddress, global.CONF.System.Port, tcpItem) - if err := server.ServeTLS(tcpKeepAliveListener{ln.(*net.TCPListener)}, certPath, keyPath); err != nil { - panic(err) - } - } else { - global.LOG.Infof("listen at http://%s:%s [%s]", global.CONF.System.BindAddress, global.CONF.System.Port, tcpItem) - if err := server.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}); err != nil { - panic(err) - } + global.LOG.Info("listen at http://0.0.0.0:9999") + if err := server.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}); err != nil { + panic(err) } } diff --git a/backend/utils/captcha/captcha.go b/backend/utils/captcha/captcha.go deleted file mode 100644 index c2f679256..000000000 --- a/backend/utils/captcha/captcha.go +++ /dev/null @@ -1,45 +0,0 @@ -package captcha - -import ( - "strings" - - "github.com/1Panel-dev/1Panel/backend/app/dto" - "github.com/1Panel-dev/1Panel/backend/constant" - "github.com/mojocn/base64Captcha" -) - -var store = base64Captcha.DefaultMemStore - -func VerifyCode(codeID string, code string) error { - if codeID == "" { - return constant.ErrCaptchaCode - } - vv := store.Get(codeID, true) - vv = strings.TrimSpace(vv) - code = strings.TrimSpace(code) - - if strings.EqualFold(vv, code) { - return nil - } - return constant.ErrCaptchaCode -} - -func CreateCaptcha() (*dto.CaptchaResponse, error) { - var driverString base64Captcha.DriverString - driverString.Source = "1234567890QWERTYUPLKJHGFDSAZXCVBNMqwertyupkjhgfdsazxcvbnm" - driverString.Width = 120 - driverString.Height = 50 - driverString.NoiseCount = 0 - driverString.Length = 4 - driverString.Fonts = []string{"RitaSmith.ttf", "actionj.ttf", "chromohv.ttf"} - driver := driverString.ConvertFonts() - c := base64Captcha.NewCaptcha(driver, store) - id, b64s, _, err := c.Generate() - if err != nil { - return nil, err - } - return &dto.CaptchaResponse{ - CaptchaID: id, - ImagePath: b64s, - }, nil -} diff --git a/backend/utils/mfa/mfa.go b/backend/utils/mfa/mfa.go deleted file mode 100644 index 30b644a5e..000000000 --- a/backend/utils/mfa/mfa.go +++ /dev/null @@ -1,46 +0,0 @@ -package mfa - -import ( - "bytes" - "encoding/base64" - "strconv" - "time" - - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/skip2/go-qrcode" - "github.com/xlzd/gotp" -) - -const secretLength = 16 - -type Otp struct { - Secret string `json:"secret"` - QrImage string `json:"qrImage"` -} - -func GetOtp(username, title string, interval int) (otp Otp, err error) { - secret := gotp.RandomSecret(secretLength) - otp.Secret = secret - totp := gotp.NewTOTP(secret, 6, interval, nil) - uri := totp.ProvisioningUri(username, title) - subImg, err := qrcode.Encode(uri, qrcode.Medium, 256) - dist := make([]byte, 3000) - base64.StdEncoding.Encode(dist, subImg) - index := bytes.IndexByte(dist, 0) - baseImage := dist[0:index] - otp.QrImage = "data:image/png;base64," + string(baseImage) - return -} - -func ValidCode(code, intervalStr, secret string) bool { - interval, err := strconv.Atoi(intervalStr) - if err != nil { - global.LOG.Errorf("type conversion failed, err: %v", err) - return false - } - totp := gotp.NewTOTP(secret, 6, interval, nil) - now := time.Now().Unix() - strInt64 := strconv.FormatInt(now, 10) - id16, _ := strconv.Atoi(strInt64) - return totp.Verify(code, int64(id16)) -} diff --git a/cmd/server/cmd/app.go b/cmd/server/cmd/app.go deleted file mode 100644 index d9a7c780e..000000000 --- a/cmd/server/cmd/app.go +++ /dev/null @@ -1,127 +0,0 @@ -package cmd - -import ( - "bytes" - "fmt" - "io" - - "github.com/1Panel-dev/1Panel/backend/utils/files" - "github.com/1Panel-dev/1Panel/cmd/server/app" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - appKey string - appVersion string -) - -func init() { - initCmd.Flags().StringVarP(&appKey, "key", "k", "", "应用的key(仅支持英文)") - initCmd.Flags().StringVarP(&appVersion, "version", "v", "", "应用版本") - appCmd.AddCommand(initCmd) - RootCmd.AddCommand(appCmd) -} - -var appCmd = &cobra.Command{ - Use: "app", - Short: "应用相关命令", -} - -var initCmd = &cobra.Command{ - Use: "init", - Short: "初始化应用", - RunE: func(cmd *cobra.Command, args []string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl app init 或者切换到 root 用户") - return nil - } - if len(args) > 0 { - appKey = args[0] - if len(args) > 1 { - appVersion = args[1] - } - } - if appKey == "" { - fmt.Println("应用的 key 缺失,使用 -k 指定") - return nil - } - if appVersion == "" { - fmt.Println("应用版本缺失,使用 -v 指定") - return nil - } - fileOp := files.NewFileOp() - appKeyPath := fmt.Sprintf("./%s", appKey) - if err := createFolder(fileOp, appKeyPath); err != nil { - return err - } - configYamlPath := fmt.Sprintf("%s/data.yml", appKeyPath) - if err := createFile(fileOp, configYamlPath); err != nil { - return err - } - if err := writeFile(fileOp, configYamlPath, bytes.NewReader(app.Config)); err != nil { - return err - } - readMePath := fmt.Sprintf("%s/README.md", appKeyPath) - if err := createFile(fileOp, readMePath); err != nil { - return err - } - logoPath := fmt.Sprintf("%s/logo.png", appKeyPath) - if err := createFile(fileOp, logoPath); err != nil { - return err - } - if err := writeFile(fileOp, logoPath, bytes.NewReader(app.Logo)); err != nil { - return err - } - versionPath := fmt.Sprintf("%s/%s", appKeyPath, appVersion) - if fileOp.Stat(versionPath) { - return errors.New("版本已存在!") - } - if err := createFolder(fileOp, versionPath); err != nil { - return err - } - versionParamPath := fmt.Sprintf("%s/%s", versionPath, "data.yml") - if err := createFile(fileOp, versionParamPath); err != nil { - return err - } - if err := writeFile(fileOp, versionParamPath, bytes.NewReader(app.Param)); err != nil { - return err - } - dockerComposeYamlPath := fmt.Sprintf("%s/%s", versionPath, "docker-compose.yml") - if err := createFile(fileOp, dockerComposeYamlPath); err != nil { - return err - } - fmt.Println("创建成功!") - return nil - }, -} - -func createFile(fileOp files.FileOp, filePath string) error { - if fileOp.Stat(filePath) { - return nil - } - if err := fileOp.CreateFile(filePath); err != nil { - fmt.Printf("文件 %s 创建失败 %v", filePath, err) - return err - } - return nil -} - -func createFolder(fileOp files.FileOp, dirPath string) error { - if fileOp.Stat(dirPath) { - return nil - } - if err := fileOp.CreateDir(dirPath, 0755); err != nil { - fmt.Printf("文件夹 %s 创建失败 %v", dirPath, err) - return err - } - return nil -} - -func writeFile(fileOp files.FileOp, filePath string, in io.Reader) error { - if err := fileOp.WriteFile(filePath, in, 0755); err != nil { - fmt.Printf("文件 %s 写入失败 %v", filePath, err) - return err - } - return nil -} diff --git a/cmd/server/cmd/listen-ip.go b/cmd/server/cmd/listen-ip.go deleted file mode 100644 index c0168878f..000000000 --- a/cmd/server/cmd/listen-ip.go +++ /dev/null @@ -1,60 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -func init() { - RootCmd.AddCommand(listenCmd) - listenCmd.AddCommand(listenIpv4Cmd) - listenCmd.AddCommand(listenIpv6Cmd) -} - -var listenCmd = &cobra.Command{ - Use: "listen-ip", - Short: "切换监听 IP", -} - -var listenIpv4Cmd = &cobra.Command{ - Use: "ipv4", - Short: "监听 IPv4", - RunE: func(cmd *cobra.Command, args []string) error { - return updateBindInfo("ipv4") - }, -} -var listenIpv6Cmd = &cobra.Command{ - Use: "ipv6", - Short: "监听 IPv6", - RunE: func(cmd *cobra.Command, args []string) error { - return updateBindInfo("ipv6") - }, -} - -func updateBindInfo(protocol string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl listen-ip ipv6 或者切换到 root 用户") - return nil - } - db, err := loadDBConn() - if err != nil { - return err - } - ipv6 := "disable" - tcp := "tcp4" - address := "0.0.0.0" - if protocol == "ipv6" { - ipv6 = "enable" - tcp = "tcp6" - address = "::" - } - if err := setSettingByKey(db, "Ipv6", ipv6); err != nil { - return err - } - if err := setSettingByKey(db, "BindAddress", address); err != nil { - return err - } - fmt.Printf("切换成功!已切换至监听 %s [%s]", tcp, address) - return nil -} diff --git a/cmd/server/cmd/reset.go b/cmd/server/cmd/reset.go deleted file mode 100644 index d398b967c..000000000 --- a/cmd/server/cmd/reset.go +++ /dev/null @@ -1,102 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -func init() { - RootCmd.AddCommand(resetCmd) - resetCmd.AddCommand(resetMFACmd) - resetCmd.AddCommand(resetSSLCmd) - resetCmd.AddCommand(resetEntranceCmd) - resetCmd.AddCommand(resetBindIpsCmd) - resetCmd.AddCommand(resetDomainCmd) -} - -var resetCmd = &cobra.Command{ - Use: "reset", - Short: "重置系统信息", -} - -var resetMFACmd = &cobra.Command{ - Use: "mfa", - Short: "取消 1Panel 两步验证", - RunE: func(cmd *cobra.Command, args []string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl reset mfa 或者切换到 root 用户") - return nil - } - db, err := loadDBConn() - if err != nil { - return err - } - - return setSettingByKey(db, "MFAStatus", "disable") - }, -} -var resetSSLCmd = &cobra.Command{ - Use: "https", - Short: "取消 1Panel https 方式登录", - RunE: func(cmd *cobra.Command, args []string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl reset https 或者切换到 root 用户") - return nil - } - db, err := loadDBConn() - if err != nil { - return err - } - - return setSettingByKey(db, "SSL", "disable") - }, -} -var resetEntranceCmd = &cobra.Command{ - Use: "entrance", - Short: "取消 1Panel 安全入口", - RunE: func(cmd *cobra.Command, args []string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl reset entrance 或者切换到 root 用户") - return nil - } - db, err := loadDBConn() - if err != nil { - return err - } - - return setSettingByKey(db, "SecurityEntrance", "") - }, -} -var resetBindIpsCmd = &cobra.Command{ - Use: "ips", - Short: "取消 1Panel 授权 IP 限制", - RunE: func(cmd *cobra.Command, args []string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl reset ips 或者切换到 root 用户") - return nil - } - db, err := loadDBConn() - if err != nil { - return err - } - - return setSettingByKey(db, "AllowIPs", "") - }, -} -var resetDomainCmd = &cobra.Command{ - Use: "domain", - Short: "取消 1Panel 访问域名绑定", - RunE: func(cmd *cobra.Command, args []string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl reset domain 或者切换到 root 用户") - return nil - } - db, err := loadDBConn() - if err != nil { - return err - } - - return setSettingByKey(db, "BindDomain", "") - }, -} diff --git a/cmd/server/cmd/restore.go b/cmd/server/cmd/restore.go deleted file mode 100644 index ba04c0fae..000000000 --- a/cmd/server/cmd/restore.go +++ /dev/null @@ -1,122 +0,0 @@ -package cmd - -import ( - "fmt" - "os" - "path" - "sort" - "strings" - "time" - - cmdUtils "github.com/1Panel-dev/1Panel/backend/utils/cmd" - "github.com/1Panel-dev/1Panel/backend/utils/common" - "github.com/pkg/errors" - - "github.com/spf13/cobra" -) - -func init() { - RootCmd.AddCommand(restoreCmd) -} - -var restoreCmd = &cobra.Command{ - Use: "restore", - Short: "回滚 1Panel 服务及数据", - RunE: func(cmd *cobra.Command, args []string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl restore 或者切换到 root 用户") - return nil - } - stdout, err := cmdUtils.Exec("grep '^BASE_DIR=' /usr/local/bin/1pctl | cut -d'=' -f2") - if err != nil { - return fmt.Errorf("handle load `BASE_DIR` failed, err: %v", err) - } - baseDir := strings.ReplaceAll(stdout, "\n", "") - upgradeDir := path.Join(baseDir, "1panel", "tmp", "upgrade") - - tmpPath, err := loadRestorePath(upgradeDir) - if err != nil { - return err - } - if tmpPath == "暂无可回滚文件" { - fmt.Println("暂无可回滚文件") - return nil - } - tmpPath = path.Join(upgradeDir, tmpPath, "original") - fmt.Printf("(0/4) 开始从 %s 目录回滚 1Panel 服务及数据... \n", tmpPath) - - if err := common.CopyFile(path.Join(tmpPath, "1panel"), "/usr/local/bin"); err != nil { - return err - } - fmt.Println("(1/4) 1panel 二进制回滚成功") - if err := common.CopyFile(path.Join(tmpPath, "1pctl"), "/usr/local/bin"); err != nil { - return err - } - fmt.Println("(2/4) 1panel 脚本回滚成功") - if err := common.CopyFile(path.Join(tmpPath, "1panel.service"), "/etc/systemd/system"); err != nil { - return err - } - fmt.Println("(3/4) 1panel 服务回滚成功") - checkPointOfWal() - if _, err := os.Stat(path.Join(tmpPath, "1Panel.db")); err == nil { - if err := common.CopyFile(path.Join(tmpPath, "1Panel.db"), path.Join(baseDir, "1panel/db")); err != nil { - return err - } - } - if _, err := os.Stat(path.Join(tmpPath, "db.tar.gz")); err == nil { - if err := handleUnTar(path.Join(tmpPath, "db.tar.gz"), path.Join(baseDir, "1panel")); err != nil { - return err - } - } - fmt.Printf("(4/4) 1panel 数据回滚成功 \n\n") - - fmt.Println("回滚成功!正在重启服务,请稍候...") - return nil - }, -} - -func checkPointOfWal() { - db, err := loadDBConn() - if err != nil { - return - } - _ = db.Exec("PRAGMA wal_checkpoint(TRUNCATE);").Error -} - -func loadRestorePath(upgradeDir string) (string, error) { - if _, err := os.Stat(upgradeDir); err != nil && os.IsNotExist(err) { - return "暂无可回滚文件", nil - } - files, err := os.ReadDir(upgradeDir) - if err != nil { - return "", err - } - var folders []string - for _, file := range files { - if file.IsDir() { - folders = append(folders, file.Name()) - } - } - if len(folders) == 0 { - return "暂无可回滚文件", nil - } - sort.Slice(folders, func(i, j int) bool { - return folders[i] > folders[j] - }) - return folders[0], nil -} - -func handleUnTar(sourceFile, targetDir string) error { - if _, err := os.Stat(targetDir); err != nil && os.IsNotExist(err) { - if err = os.MkdirAll(targetDir, os.ModePerm); err != nil { - return err - } - } - - commands := fmt.Sprintf("tar zxvfC %s %s", sourceFile, targetDir) - stdout, err := cmdUtils.ExecWithTimeOut(commands, 20*time.Second) - if err != nil { - return errors.New(stdout) - } - return nil -} diff --git a/cmd/server/cmd/root.go b/cmd/server/cmd/root.go deleted file mode 100644 index 78023bd3b..000000000 --- a/cmd/server/cmd/root.go +++ /dev/null @@ -1,80 +0,0 @@ -package cmd - -import ( - "fmt" - "os/user" - "strings" - "time" - - "github.com/1Panel-dev/1Panel/backend/server" - cmdUtils "github.com/1Panel-dev/1Panel/backend/utils/cmd" - "github.com/glebarez/sqlite" - "github.com/spf13/cobra" - "gorm.io/gorm" -) - -func init() {} - -var RootCmd = &cobra.Command{ - Use: "1panel", - Short: "1Panel ,一款现代化的 Linux 面板", - RunE: func(cmd *cobra.Command, args []string) error { - server.Start() - return nil - }, -} - -type setting struct { - ID uint `gorm:"primarykey;AUTO_INCREMENT" json:"id"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - Key string `json:"key" gorm:"type:varchar(256);not null;"` - Value string `json:"value" gorm:"type:varchar(256)"` - About string `json:"about" gorm:"type:longText"` -} - -func loadDBConn() (*gorm.DB, error) { - stdout, err := cmdUtils.Exec("grep '^BASE_DIR=' /usr/local/bin/1pctl | cut -d'=' -f2") - if err != nil { - return nil, fmt.Errorf("handle load `BASE_DIR` failed, err: %v", err) - } - baseDir := strings.ReplaceAll(stdout, "\n", "") - if len(baseDir) == 0 { - return nil, fmt.Errorf("error `BASE_DIR` find in /usr/local/bin/1pctl \n") - } - if strings.HasSuffix(baseDir, "/") { - baseDir = baseDir[:strings.LastIndex(baseDir, "/")] - } - - db, err := gorm.Open(sqlite.Open(baseDir+"/1panel/db/1Panel.db"), &gorm.Config{}) - if err != nil { - return nil, fmt.Errorf("init my db conn failed, err: %v \n", err) - } - return db, nil -} - -func getSettingByKey(db *gorm.DB, key string) string { - var setting setting - _ = db.Where("key = ?", key).First(&setting).Error - return setting.Value -} - -type LoginLog struct{} - -func isDefault(db *gorm.DB) bool { - logCount := int64(0) - _ = db.Model(&LoginLog{}).Where("status = ?", "Success").Count(&logCount).Error - return logCount == 0 -} - -func setSettingByKey(db *gorm.DB, key, value string) error { - return db.Model(&setting{}).Where("key = ?", key).Updates(map[string]interface{}{"value": value}).Error -} - -func isRoot() bool { - currentUser, err := user.Current() - if err != nil { - return false - } - return currentUser.Uid == "0" -} diff --git a/cmd/server/cmd/update.go b/cmd/server/cmd/update.go deleted file mode 100644 index 706862cc5..000000000 --- a/cmd/server/cmd/update.go +++ /dev/null @@ -1,240 +0,0 @@ -package cmd - -import ( - "bufio" - "fmt" - "os" - "regexp" - "strconv" - "strings" - "unicode" - - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/1Panel-dev/1Panel/backend/utils/cmd" - "github.com/1Panel-dev/1Panel/backend/utils/common" - "github.com/1Panel-dev/1Panel/backend/utils/encrypt" - "github.com/spf13/cobra" - "golang.org/x/term" -) - -func init() { - RootCmd.AddCommand(updateCmd) - updateCmd.AddCommand(updateUserName) - updateCmd.AddCommand(updatePassword) - updateCmd.AddCommand(updatePort) -} - -var updateCmd = &cobra.Command{ - Use: "update", - Short: "修改面板信息", -} - -var updateUserName = &cobra.Command{ - Use: "username", - Short: "修改面板用户", - RunE: func(cmd *cobra.Command, args []string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl update username 或者切换到 root 用户") - return nil - } - username() - return nil - }, -} -var updatePassword = &cobra.Command{ - Use: "password", - Short: "修改面板密码", - RunE: func(cmd *cobra.Command, args []string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl update password 或者切换到 root 用户") - return nil - } - password() - return nil - }, -} -var updatePort = &cobra.Command{ - Use: "port", - Short: "修改面板端口", - RunE: func(cmd *cobra.Command, args []string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl update port 或者切换到 root 用户") - return nil - } - port() - return nil - }, -} - -func username() { - reader := bufio.NewReader(os.Stdin) - fmt.Print("修改面板用户: ") - newUsername, _ := reader.ReadString('\n') - newUsername = strings.Trim(newUsername, "\n") - if len(newUsername) == 0 { - fmt.Println("错误:输入面板用户为空!") - return - } - if strings.Contains(newUsername, " ") { - fmt.Println("错误:输入面板用户中包含空格字符!") - return - } - result, err := regexp.MatchString("^[a-zA-Z0-9_\u4e00-\u9fa5]{3,30}$", newUsername) - if !result || err != nil { - fmt.Println("错误:输入面板用户错误!仅支持英文、中文、数字和_,长度3-30") - return - } - - db, err := loadDBConn() - if err != nil { - fmt.Printf("错误:初始化数据库连接失败,%v\n", err) - return - } - if err := setSettingByKey(db, "UserName", newUsername); err != nil { - fmt.Printf("错误:面板用户修改失败,%v\n", err) - return - } - - fmt.Printf("修改成功!\n\n") - fmt.Printf("面板用户:%s\n", newUsername) -} - -func password() { - fmt.Print("修改面板密码:") - bytePassword, err := term.ReadPassword(int(os.Stdin.Fd())) - if err != nil { - fmt.Printf("\n错误:面板密码信息读取错误,%v\n", err) - return - } - newPassword := string(bytePassword) - newPassword = strings.Trim(newPassword, "\n") - - if len(newPassword) == 0 { - fmt.Println("\n错误:输入面板密码为空!") - return - } - if strings.Contains(newPassword, " ") { - fmt.Println("\n错误:输入面板密码中包含空格字符!") - return - } - db, err := loadDBConn() - if err != nil { - fmt.Printf("\n错误:初始化数据库连接失败,%v\n", err) - return - } - complexSetting := getSettingByKey(db, "ComplexityVerification") - if complexSetting == "enable" { - if isValidPassword("newPassword") { - fmt.Println("\n错误:面板密码仅支持字母、数字、特殊字符(!@#$%*_,.?),长度 8-30 位!") - return - } - } - if len(newPassword) < 6 { - fmt.Println("错误:请输入 6 位以上密码!") - return - } - - fmt.Print("\n确认密码:") - byteConfirmPassword, err := term.ReadPassword(int(os.Stdin.Fd())) - if err != nil { - fmt.Printf("\n错误:面板密码信息读取错误,%v\n", err) - return - } - confirmPassword := string(byteConfirmPassword) - confirmPassword = strings.Trim(confirmPassword, "\n") - - if newPassword != confirmPassword { - fmt.Printf("\n错误:两次密码不匹配,请检查后重试!,%v\n", err) - return - } - - p := "" - encryptSetting := getSettingByKey(db, "EncryptKey") - if len(encryptSetting) == 16 { - global.CONF.System.EncryptKey = encryptSetting - p, _ = encrypt.StringEncrypt(newPassword) - } else { - p = newPassword - } - if err := setSettingByKey(db, "Password", p); err != nil { - fmt.Printf("\n错误:面板密码修改失败,%v\n", err) - return - } - username := getSettingByKey(db, "UserName") - - fmt.Printf("\n修改成功!\n\n") - fmt.Printf("面板用户:%s\n", username) - fmt.Printf("面板密码:%s\n", string(newPassword)) -} - -func port() { - reader := bufio.NewReader(os.Stdin) - fmt.Print("修改面板端口:") - - newPortStr, _ := reader.ReadString('\n') - newPortStr = strings.Trim(newPortStr, "\n") - newPort, err := strconv.Atoi(strings.TrimSpace(newPortStr)) - if err != nil || newPort < 1 || newPort > 65535 { - fmt.Println("错误:输入的端口号必须在 1 到 65535 之间!") - return - } - if common.ScanPort(newPort) { - fmt.Println("错误:该端口号正被占用,请检查后重试!") - return - } - db, err := loadDBConn() - if err != nil { - fmt.Printf("错误:初始化数据库连接失败,%v\n", err) - return - } - if err := setSettingByKey(db, "ServerPort", newPortStr); err != nil { - fmt.Printf("错误:面板端口修改失败,%v\n", err) - return - } - - fmt.Printf("修改成功!\n\n") - fmt.Printf("面板端口:%s\n", newPortStr) - - std, err := cmd.Exec("1pctl restart") - if err != nil { - fmt.Println(std) - } -} -func isValidPassword(password string) bool { - numCount := 0 - alphaCount := 0 - specialCount := 0 - - for _, char := range password { - switch { - case unicode.IsDigit(char): - numCount++ - case unicode.IsLetter(char): - alphaCount++ - case isSpecialChar(char): - specialCount++ - } - } - - if len(password) < 8 && len(password) > 30 { - return false - } - if (numCount == 0 && alphaCount == 0) || (alphaCount == 0 && specialCount == 0) || (numCount == 0 && specialCount == 0) { - return false - } - return true -} - -func isSpecialChar(char rune) bool { - specialChars := "!@#$%*_,.?" - return unicode.IsPunct(char) && contains(specialChars, char) -} - -func contains(specialChars string, char rune) bool { - for _, c := range specialChars { - if c == char { - return true - } - } - return false -} diff --git a/cmd/server/cmd/user-info.go b/cmd/server/cmd/user-info.go deleted file mode 100644 index c13a8efa5..000000000 --- a/cmd/server/cmd/user-info.go +++ /dev/null @@ -1,56 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/1Panel-dev/1Panel/backend/utils/encrypt" - "github.com/spf13/cobra" -) - -func init() { - RootCmd.AddCommand(userinfoCmd) -} - -var userinfoCmd = &cobra.Command{ - Use: "user-info", - Short: "获取面板信息", - RunE: func(cmd *cobra.Command, args []string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl user-info 或者切换到 root 用户") - return nil - } - db, err := loadDBConn() - if err != nil { - return fmt.Errorf("init my db conn failed, err: %v \n", err) - } - user := getSettingByKey(db, "UserName") - pass := "********" - if isDefault(db) { - encryptSetting := getSettingByKey(db, "EncryptKey") - pass = getSettingByKey(db, "Password") - if len(encryptSetting) == 16 { - global.CONF.System.EncryptKey = encryptSetting - pass, _ = encrypt.StringDecrypt(pass) - } - } - port := getSettingByKey(db, "ServerPort") - ssl := getSettingByKey(db, "SSL") - entrance := getSettingByKey(db, "SecurityEntrance") - address := getSettingByKey(db, "SystemIP") - - protocol := "http" - if ssl == "enable" { - protocol = "https" - } - if address == "" { - address = "$LOCAL_IP" - } - - fmt.Printf("面板地址: %s://%s:%s/%s \n", protocol, address, port, entrance) - fmt.Println("面板用户: ", user) - fmt.Println("面板密码: ", pass) - fmt.Println("提示:修改密码可执行命令:1pctl update password") - return nil - }, -} diff --git a/cmd/server/cmd/version.go b/cmd/server/cmd/version.go deleted file mode 100644 index e40faff3e..000000000 --- a/cmd/server/cmd/version.go +++ /dev/null @@ -1,40 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/1Panel-dev/1Panel/backend/configs" - "github.com/1Panel-dev/1Panel/cmd/server/conf" - "gopkg.in/yaml.v3" - - "github.com/spf13/cobra" -) - -func init() { - RootCmd.AddCommand(versionCmd) -} - -var versionCmd = &cobra.Command{ - Use: "version", - Short: "获取系统版本信息", - RunE: func(cmd *cobra.Command, args []string) error { - if !isRoot() { - fmt.Println("请使用 sudo 1pctl version 或者切换到 root 用户") - return nil - } - db, err := loadDBConn() - if err != nil { - return err - } - version := getSettingByKey(db, "SystemVersion") - - fmt.Printf("1panel version: %s\n", version) - config := configs.ServerConfig{} - if err := yaml.Unmarshal(conf.AppYaml, &config); err != nil { - return fmt.Errorf("unmarshal conf.App.Yaml failed, errL %v", err) - } else { - fmt.Printf("mode: %s\n", config.System.Mode) - } - return nil - }, -} diff --git a/cmd/server/main.go b/cmd/server/main.go index d0aefa1b5..7a45faa10 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -1,12 +1,10 @@ package main import ( - "fmt" - "os" - - "github.com/1Panel-dev/1Panel/cmd/server/cmd" - _ "github.com/1Panel-dev/1Panel/cmd/server/docs" _ "net/http/pprof" + + _ "github.com/1Panel-dev/1Panel/cmd/server/docs" + "github.com/1Panel-dev/1Panel/server" ) // @title 1Panel @@ -20,8 +18,5 @@ import ( //go:generate swag init -o ./docs -g main.go -d ../../backend -g ../cmd/server/main.go func main() { - if err := cmd.RootCmd.Execute(); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } + server.Start() } diff --git a/cmd/server/web/favicon.png b/cmd/server/web/favicon.png deleted file mode 100644 index 6f82a12d5..000000000 Binary files a/cmd/server/web/favicon.png and /dev/null differ diff --git a/cmd/server/web/web.go b/cmd/server/web/web.go deleted file mode 100644 index dc7a3d3b0..000000000 --- a/cmd/server/web/web.go +++ /dev/null @@ -1,15 +0,0 @@ -package web - -import "embed" - -//go:embed index.html -var IndexHtml embed.FS - -//go:embed assets/* -var Assets embed.FS - -//go:embed index.html -var IndexByte []byte - -//go:embed favicon.png -var Favicon embed.FS diff --git a/core/.gitignore b/core/.gitignore new file mode 100644 index 000000000..70048d63a --- /dev/null +++ b/core/.gitignore @@ -0,0 +1,55 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +build/1panel + +# Mac +.DS_Store +*/.DS_Store + +# VS Code +.vscode +*.project +*.factorypath + +# IntelliJ IDEA +.idea/* +!.idea/icon.png +*.iws +*.iml +*.ipr + + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories +/pkg/ +backend/__debug_bin +cmd/server/__debug_bin +cmd/server/web/assets +cmd/server/web/monacoeditorwork +cmd/server/web/index.html +frontend/auto-imports.d.ts +frontend/components.d.ts +frontend/src/xpack +backend/xpack +backend/router/entry_xpack.go +backend/server/init_xpack.go +backend/utils/xpack/xpack_xpack.go + +.history/ +dist/ +1pctl +1panel.service +install.sh +quick_start.sh +cmd/server/fileList.txt +.fileList.txt +1Panel.code-workspace diff --git a/core/app/api/v1/helper/helper.go b/core/app/api/v1/helper/helper.go index 257c3e166..5e6bf7e8b 100644 --- a/core/app/api/v1/helper/helper.go +++ b/core/app/api/v1/helper/helper.go @@ -25,8 +25,8 @@ func ErrorWithDetail(ctx *gin.Context, code int, msgKey string, err error) { res.Message = i18n.GetMsgWithMap("ErrRecordNotFound", nil) case errors.Is(constant.ErrInvalidParams, err): res.Message = i18n.GetMsgWithMap("ErrInvalidParams", nil) - case errors.Is(constant.ErrStructTransform, err): - res.Message = i18n.GetMsgWithMap("ErrStructTransform", map[string]interface{}{"detail": err}) + case errors.Is(constant.ErrTransform, err): + res.Message = i18n.GetMsgWithMap("ErrTransform", map[string]interface{}{"detail": err}) case errors.Is(constant.ErrCaptchaCode, err): res.Code = constant.CodeAuth res.Message = "ErrCaptchaCode" diff --git a/core/app/dto/common_req.go b/core/app/dto/common_req.go index b493fac55..b7804ab26 100644 --- a/core/app/dto/common_req.go +++ b/core/app/dto/common_req.go @@ -9,46 +9,3 @@ type PageInfo struct { Page int `json:"page" validate:"required,number"` PageSize int `json:"pageSize" validate:"required,number"` } - -type UpdateDescription struct { - ID uint `json:"id" validate:"required"` - Description string `json:"description" validate:"max=256"` -} - -type OperationWithName struct { - Name string `json:"name" validate:"required"` -} - -type OperateByID struct { - ID uint `json:"id" validate:"required"` -} - -type Operate struct { - Operation string `json:"operation" validate:"required"` -} - -type BatchDeleteReq struct { - Ids []uint `json:"ids" validate:"required"` -} - -type FilePath struct { - Path string `json:"path" validate:"required"` -} - -type DeleteByName struct { - Name string `json:"name" validate:"required"` -} - -type UpdateByFile struct { - File string `json:"file"` -} - -type UpdateByNameAndFile struct { - Name string `json:"name"` - File string `json:"file"` -} - -type OperationWithNameAndType struct { - Name string `json:"name"` - Type string `json:"type" validate:"required"` -} diff --git a/core/app/dto/setting.go b/core/app/dto/setting.go index 29f8b24a2..35522a08b 100644 --- a/core/app/dto/setting.go +++ b/core/app/dto/setting.go @@ -3,18 +3,11 @@ package dto import "time" type SettingInfo struct { - UserName string `json:"userName"` - Email string `json:"email"` - SystemIP string `json:"systemIP"` - SystemVersion string `json:"systemVersion"` - DockerSockPath string `json:"dockerSockPath"` - DeveloperMode string `json:"developerMode"` + UserName string `json:"userName"` + SystemVersion string `json:"systemVersion"` + DeveloperMode string `json:"developerMode"` SessionTimeout string `json:"sessionTimeout"` - LocalTime string `json:"localTime"` - TimeZone string `json:"timeZone"` - NtpSite string `json:"ntpSite"` - Port string `json:"port"` Ipv6 string `json:"ipv6"` BindAddress string `json:"bindAddress"` @@ -22,10 +15,6 @@ type SettingInfo struct { Theme string `json:"theme"` MenuTabs string `json:"menuTabs"` Language string `json:"language"` - DefaultNetwork string `json:"defaultNetwork"` - LastCleanTime string `json:"lastCleanTime"` - LastCleanSize string `json:"lastCleanSize"` - LastCleanData string `json:"lastCleanData"` ServerPort string `json:"serverPort"` SSL string `json:"ssl"` @@ -40,24 +29,12 @@ type SettingInfo struct { MFASecret string `json:"mfaSecret"` MFAInterval string `json:"mfaInterval"` - MonitorStatus string `json:"monitorStatus"` - MonitorInterval string `json:"monitorInterval"` - MonitorStoreDays string `json:"monitorStoreDays"` - - MessageType string `json:"messageType"` - EmailVars string `json:"emailVars"` - WeChatVars string `json:"weChatVars"` - DingVars string `json:"dingVars"` - AppStoreVersion string `json:"appStoreVersion"` AppStoreLastModified string `json:"appStoreLastModified"` AppStoreSyncStatus string `json:"appStoreSyncStatus"` - FileRecycleBin string `json:"fileRecycleBin"` - - SnapshotIgnore string `json:"snapshotIgnore"` - XpackHideMenu string `json:"xpackHideMenu"` - NoAuthSetting string `json:"noAuthSetting"` + XpackHideMenu string `json:"xpackHideMenu"` + NoAuthSetting string `json:"noAuthSetting"` ProxyUrl string `json:"proxyUrl"` ProxyType string `json:"proxyType"` diff --git a/core/app/repo/common.go b/core/app/repo/common.go index 1cb726c2a..4610cd1f4 100644 --- a/core/app/repo/common.go +++ b/core/app/repo/common.go @@ -1,28 +1,13 @@ package repo import ( - "fmt" - "time" - - "github.com/1Panel-dev/1Panel/core/constant" "gorm.io/gorm" ) type DBOption func(*gorm.DB) *gorm.DB type ICommonRepo interface { - WithByID(id uint) DBOption - WithByName(name string) DBOption - WithByType(tp string) DBOption WithOrderBy(orderStr string) DBOption - WithOrderRuleBy(orderBy, order string) DBOption - WithByGroupID(groupID uint) DBOption - WithLikeName(name string) DBOption - WithIdsIn(ids []uint) DBOption - WithByDate(startTime, endTime time.Time) DBOption - WithByStartDate(startTime time.Time) DBOption - WithByStatus(status string) DBOption - WithByFrom(from string) DBOption } type CommonRepo struct{} @@ -30,99 +15,8 @@ type CommonRepo struct{} func NewCommonRepo() ICommonRepo { return &CommonRepo{} } - -func (c *CommonRepo) WithByID(id uint) DBOption { - return func(g *gorm.DB) *gorm.DB { - return g.Where("id = ?", id) - } -} - -func (c *CommonRepo) WithByName(name string) DBOption { - return func(g *gorm.DB) *gorm.DB { - return g.Where("name = ?", name) - } -} - -func (c *CommonRepo) WithByDate(startTime, endTime time.Time) DBOption { - return func(g *gorm.DB) *gorm.DB { - return g.Where("start_time > ? AND start_time < ?", startTime, endTime) - } -} - -func (c *CommonRepo) WithByStartDate(startTime time.Time) DBOption { - return func(g *gorm.DB) *gorm.DB { - return g.Where("start_time < ?", startTime) - } -} - -func (c *CommonRepo) WithByType(tp string) DBOption { - return func(g *gorm.DB) *gorm.DB { - return g.Where("type = ?", tp) - } -} - -func (c *CommonRepo) WithByGroupID(groupID uint) DBOption { - return func(g *gorm.DB) *gorm.DB { - if groupID == 0 { - return g - } - return g.Where("group_id = ?", groupID) - } -} - -func (c *CommonRepo) WithByStatus(status string) DBOption { - return func(g *gorm.DB) *gorm.DB { - if len(status) == 0 { - return g - } - return g.Where("status = ?", status) - } -} - -func (c *CommonRepo) WithByFrom(from string) DBOption { - return func(g *gorm.DB) *gorm.DB { - return g.Where("`from` = ?", from) - } -} - -func (c *CommonRepo) WithLikeName(name string) DBOption { - return func(g *gorm.DB) *gorm.DB { - if len(name) == 0 { - return g - } - return g.Where("name like ?", "%"+name+"%") - } -} - func (c *CommonRepo) WithOrderBy(orderStr string) DBOption { return func(g *gorm.DB) *gorm.DB { return g.Order(orderStr) } } - -func (c *CommonRepo) WithOrderRuleBy(orderBy, order string) DBOption { - switch order { - case constant.OrderDesc: - order = "desc" - case constant.OrderAsc: - order = "asc" - default: - orderBy = "created_at" - order = "desc" - } - return func(g *gorm.DB) *gorm.DB { - return g.Order(fmt.Sprintf("%s %s", orderBy, order)) - } -} - -func (c *CommonRepo) WithIdsIn(ids []uint) DBOption { - return func(g *gorm.DB) *gorm.DB { - return g.Where("id in (?)", ids) - } -} - -func (c *CommonRepo) WithIdsNotIn(ids []uint) DBOption { - return func(g *gorm.DB) *gorm.DB { - return g.Where("id not in (?)", ids) - } -} diff --git a/core/app/service/logs.go b/core/app/service/logs.go index ffafb46e2..1cd6afa96 100644 --- a/core/app/service/logs.go +++ b/core/app/service/logs.go @@ -85,7 +85,7 @@ func (u *LogService) PageLoginLog(req dto.SearchLgLogWithPage) (int64, interface for _, op := range ops { var item dto.LoginLog if err := copier.Copy(&item, &op); err != nil { - return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error()) + return 0, nil, errors.WithMessage(constant.ErrTransform, err.Error()) } dtoOps = append(dtoOps, item) } @@ -109,7 +109,7 @@ func (u *LogService) PageOperationLog(req dto.SearchOpLogWithPage) (int64, inter for _, op := range ops { var item dto.OperationLog if err := copier.Copy(&item, &op); err != nil { - return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error()) + return 0, nil, errors.WithMessage(constant.ErrTransform, err.Error()) } dtoOps = append(dtoOps, item) } diff --git a/core/app/service/setting.go b/core/app/service/setting.go index 9115efd1d..08c342b83 100644 --- a/core/app/service/setting.go +++ b/core/app/service/setting.go @@ -65,7 +65,6 @@ func (u *SettingService) GetSettingInfo() (*dto.SettingInfo, error) { info.ProxyPasswd, _ = encrypt.StringDecrypt(info.ProxyPasswd) } - info.LocalTime = time.Now().Format("2006-01-02 15:04:05 MST -0700") return &info, err } diff --git a/core/cmd/server/conf/qqwry/qqwey.go b/core/cmd/server/conf/qqwry/qqwey.go new file mode 100644 index 000000000..94ee4abb8 --- /dev/null +++ b/core/cmd/server/conf/qqwry/qqwey.go @@ -0,0 +1,6 @@ +package qqwry + +import _ "embed" + +//go:embed qqwry.dat +var QQwryByte []byte diff --git a/core/cmd/server/conf/qqwry/qqwry.dat b/core/cmd/server/conf/qqwry/qqwry.dat new file mode 100644 index 000000000..0752ec831 Binary files /dev/null and b/core/cmd/server/conf/qqwry/qqwry.dat differ diff --git a/core/main.go b/core/cmd/server/main.go similarity index 100% rename from core/main.go rename to core/cmd/server/main.go diff --git a/core/constant/dir.go b/core/constant/dir.go index 931b21c22..cdb8de0dd 100644 --- a/core/constant/dir.go +++ b/core/constant/dir.go @@ -1,20 +1,9 @@ package constant import ( - "path" - "github.com/1Panel-dev/1Panel/core/global" ) var ( - DataDir = global.CONF.System.DataDir - ResourceDir = path.Join(DataDir, "resource") - AppResourceDir = path.Join(ResourceDir, "apps") - AppInstallDir = path.Join(DataDir, "apps") - LocalAppResourceDir = path.Join(AppResourceDir, "local") - LocalAppInstallDir = path.Join(AppInstallDir, "local") - RemoteAppResourceDir = path.Join(AppResourceDir, "remote") - RuntimeDir = path.Join(DataDir, "runtime") - RecycleBinDir = "/.1panel_clash" - SSLLogDir = path.Join(global.CONF.System.DataDir, "log", "ssl") + DataDir = global.CONF.System.DataDir ) diff --git a/core/constant/errs.go b/core/constant/errs.go index 411387d3d..f829c7f33 100644 --- a/core/constant/errs.go +++ b/core/constant/errs.go @@ -27,12 +27,13 @@ var ( ErrAuth = errors.New("ErrAuth") ErrRecordExist = errors.New("ErrRecordExist") ErrRecordNotFound = errors.New("ErrRecordNotFound") - ErrStructTransform = errors.New("ErrStructTransform") + ErrTransform = errors.New("ErrTransform") ErrInitialPassword = errors.New("ErrInitialPassword") - ErrNotSupportType = errors.New("ErrNotSupportType") ErrInvalidParams = errors.New("ErrInvalidParams") ErrTokenParse = errors.New("ErrTokenParse") + ErrPortInUsed = "ErrPortInUsed" + ErrCmdTimeout = "ErrCmdTimeout" ) // api @@ -41,124 +42,6 @@ var ( ErrTypeInvalidParams = "ErrInvalidParams" ErrTypeNotLogin = "ErrNotLogin" ErrTypePasswordExpired = "ErrPasswordExpired" - ErrNameIsExist = "ErrNameIsExist" ErrDemoEnvironment = "ErrDemoEnvironment" - ErrCmdIllegal = "ErrCmdIllegal" - ErrXpackNotFound = "ErrXpackNotFound" - ErrXpackNotActive = "ErrXpackNotActive" - ErrXpackOutOfDate = "ErrXpackOutOfDate" -) - -// app -var ( - ErrPortInUsed = "ErrPortInUsed" - ErrAppLimit = "ErrAppLimit" - ErrFileCanNotRead = "ErrFileCanNotRead" - ErrNotInstall = "ErrNotInstall" - ErrPortInOtherApp = "ErrPortInOtherApp" - ErrDbUserNotValid = "ErrDbUserNotValid" - ErrUpdateBuWebsite = "ErrUpdateBuWebsite" - Err1PanelNetworkFailed = "Err1PanelNetworkFailed" - ErrCmdTimeout = "ErrCmdTimeout" - ErrFileParse = "ErrFileParse" - ErrInstallDirNotFound = "ErrInstallDirNotFound" - ErrContainerName = "ErrContainerName" - ErrAppNameExist = "ErrAppNameExist" - ErrFileNotFound = "ErrFileNotFound" - ErrFileParseApp = "ErrFileParseApp" - ErrAppParamKey = "ErrAppParamKey" -) - -// website -var ( - ErrDomainIsExist = "ErrDomainIsExist" - ErrAliasIsExist = "ErrAliasIsExist" - ErrGroupIsUsed = "ErrGroupIsUsed" - ErrUsernameIsExist = "ErrUsernameIsExist" - ErrUsernameIsNotExist = "ErrUsernameIsNotExist" - ErrBackupMatch = "ErrBackupMatch" - ErrBackupExist = "ErrBackupExist" - ErrDomainIsUsed = "ErrDomainIsUsed" -) - -// ssl -var ( - ErrSSLCannotDelete = "ErrSSLCannotDelete" - ErrAccountCannotDelete = "ErrAccountCannotDelete" - ErrSSLApply = "ErrSSLApply" - ErrEmailIsExist = "ErrEmailIsExist" - ErrEabKidOrEabHmacKeyCannotBlank = "ErrEabKidOrEabHmacKeyCannotBlank" -) - -// file -var ( - ErrPathNotFound = "ErrPathNotFound" - ErrMovePathFailed = "ErrMovePathFailed" - ErrLinkPathNotFound = "ErrLinkPathNotFound" - ErrFileIsExist = "ErrFileIsExist" - ErrFileUpload = "ErrFileUpload" - ErrFileDownloadDir = "ErrFileDownloadDir" - ErrCmdNotFound = "ErrCmdNotFound" - ErrFavoriteExist = "ErrFavoriteExist" -) - -// mysql -var ( - ErrUserIsExist = "ErrUserIsExist" - ErrDatabaseIsExist = "ErrDatabaseIsExist" - ErrExecTimeOut = "ErrExecTimeOut" - ErrRemoteExist = "ErrRemoteExist" - ErrLocalExist = "ErrLocalExist" -) - -// redis -var ( - ErrTypeOfRedis = "ErrTypeOfRedis" -) - -// container -var ( - ErrInUsed = "ErrInUsed" - ErrObjectInUsed = "ErrObjectInUsed" - ErrPortRules = "ErrPortRules" - ErrPgImagePull = "ErrPgImagePull" -) - -// runtime -var ( - ErrDirNotFound = "ErrDirNotFound" - ErrFileNotExist = "ErrFileNotExist" - ErrImageBuildErr = "ErrImageBuildErr" - ErrImageExist = "ErrImageExist" - ErrDelWithWebsite = "ErrDelWithWebsite" - ErrRuntimeStart = "ErrRuntimeStart" - ErrPackageJsonNotFound = "ErrPackageJsonNotFound" - ErrScriptsNotFound = "ErrScriptsNotFound" -) - -var ( - ErrBackupInUsed = "ErrBackupInUsed" - ErrOSSConn = "ErrOSSConn" - ErrEntrance = "ErrEntrance" -) - -var ( - ErrFirewall = "ErrFirewall" -) - -// cronjob -var ( - ErrBashExecute = "ErrBashExecute" -) - -var ( - ErrNotExistUser = "ErrNotExistUser" -) - -// license -var ( - ErrLicense = "ErrLicense" - ErrLicenseCheck = "ErrLicenseCheck" - ErrLicenseSave = "ErrLicenseSave" - ErrLicenseSync = "ErrLicenseSync" + ErrEntrance = "ErrEntrance" ) diff --git a/core/i18n/lang/en.yaml b/core/i18n/lang/en.yaml index a3582c69f..f5cfc4b39 100644 --- a/core/i18n/lang/en.yaml +++ b/core/i18n/lang/en.yaml @@ -4,7 +4,7 @@ ErrInitialPassword: "Initial password error" ErrInternalServer: "Service internal error: {{ .detail }}" ErrRecordExist: "Record already exists" ErrRecordNotFound: "Records not found" -ErrStructTransform: "Type conversion failure: {{ .detail }}" +ErrTransform: "Type conversion failure: {{ .detail }}" ErrNotLogin: "User is not Login: {{ .detail }}" ErrPasswordExpired: "The current password has expired: {{ .detail }}" ErrNotSupportType: "The system does not support the current type: {{ .detail }}" @@ -12,187 +12,12 @@ ErrNotSupportType: "The system does not support the current type: {{ .detail }}" #common ErrNameIsExist: "Name is already exist" ErrDemoEnvironment: "Demo server, prohibit this operation!" -ErrCmdTimeout: "Command execution timed out!" -ErrCmdIllegal: "The command contains illegal characters. Please modify and try again!" -ErrPortExist: '{{ .port }} port is already occupied by {{ .type }} [{{ .name }}]' -TYPE_APP: "Application" -TYPE_RUNTIME: "Runtime environment" -TYPE_DOMAIN: "Domain name" -ErrTypePort: 'Port {{ .name }} format error' -ErrTypePortRange: 'Port range needs to be between 1-65535' -Success: "Success" -Failed: "Failed" -SystemRestart: "System restart causes task interruption" +ErrEntrance: "Security entrance information error. Please check and try again!" #app ErrPortInUsed: "{{ .detail }} port already in use" -ErrAppLimit: "App exceeds install limit" -ErrAppRequired: "{{ .detail }} app is required" -ErrNotInstall: "App not installed" -ErrPortInOtherApp: "{{ .port }} port already in use by app {{ .apps }}" -ErrDbUserNotValid: "Stock database, username and password do not match!" -ErrDockerComposeNotValid: "docker-compose file format error!" -ErrUpdateBuWebsite: 'The application was updated successfully, but the modification of the website configuration file failed, please check the configuration!' -Err1PanelNetworkFailed: 'Default container network creation failed! {{ .detail }}' -ErrFileParse: 'Application docker-compose file parsing failed!' -ErrInstallDirNotFound: 'installation directory does not exist' -AppStoreIsUpToDate: 'The app store is already up to date!' -LocalAppVersionNull: 'The {{.name}} app is not synced to version! Could not add to application list' -LocalAppVersionErr: '{{.name}} failed to sync version {{.version}}! {{.err}}' -ErrFileNotFound: '{{.name}} file does not exist' -ErrFileParseApp: 'Failed to parse {{.name}} file {{.err}}' -ErrAppDirNull: 'version folder does not exist' -LocalAppErr: "App {{.name}} sync failed! {{.err}}" -ErrContainerName: "ContainerName is already exist" -ErrAppSystemRestart: "1Panel restart causes the task to terminate" ErrCreateHttpClient: "Failed to create HTTP request {{.err}}" ErrHttpReqTimeOut: "Request timed out {{.err}}" ErrHttpReqFailed: "Request failed {{.err}}" ErrHttpReqNotFound: "The file does not exist" -ErrNoSuchHost: "Network connection failed" -ErrImagePullTimeOut: 'Image pull timeout' -ErrContainerNotFound: '{{ .name }} container does not exist' -ErrContainerMsg: '{{ .name }} container is abnormal, please check the log on the container page for details' -ErrAppBackup: '{{ .name }} application backup failed err {{.err}}' -ErrImagePull: '{{ .name }} image pull failed err {{.err}}' -ErrVersionTooLow: 'The current 1Panel version is too low to update the app store, please upgrade the version' -ErrAppNameExist: 'App name is already exist' -AppStoreIsSyncing: 'The App Store is syncing, please try again later' -ErrGetCompose: "Failed to obtain docker-compose.yml file! {{ .detail }}" -ErrAppWarn: "Abnormal status, please check the log" -ErrAppParamKey: "Parameter {{ .name }} field exception" -ErrAppUpgrade: "Failed to upgrade application {{ .name }} {{ .err }}" -AppRecover: "App {{ .name }} rolled back " -PullImageStart: "Start pulling image {{ .name }}" -PullImageSuccess: "Image pulled successfully" -UpgradeAppStart: "Start upgrading application {{ .name }}" -UpgradeAppSuccess: "App {{ .name }} upgraded successfully" - -#file -ErrFileCanNotRead: "File can not read" -ErrFileToLarge: "file is too large" -ErrPathNotFound: "Path is not found" -ErrMovePathFailed: "The target path cannot contain the original path!" -ErrLinkPathNotFound: "Target path does not exist!" -ErrFileIsExist: "File or directory already exists!" -ErrFileUpload: "Failed to upload file {{.name}} {{.detail}}" -ErrFileDownloadDir: "Download folder not supported" -ErrCmdNotFound: "{{ .name}} command does not exist, please install this command on the host first" -ErrSourcePathNotFound: "Source directory does not exist" -ErrFavoriteExist: "This path has been collected" -ErrInvalidChar: "Illegal characters are prohibited" - -#website -ErrDomainIsExist: "Domain is already exist" -ErrAliasIsExist: "Alias is already exist" -ErrAppDelete: 'Other Website use this App' -ErrGroupIsUsed: 'The group is in use and cannot be deleted' -ErrBackupMatch: 'the backup file does not match the current partial data of the website: {{ .detail}}' -ErrBackupExist: 'the backup file corresponds to a portion of the original data that does not exist: {{ .detail}}' -ErrPHPResource: 'The local runtime does not support switching!' -ErrPathPermission: 'A folder with non-1000:1000 permissions was detected in the index directory, which may cause an Access denied error when accessing the website. Please click the save button above' -ErrDomainIsUsed: "Domain is already used by website {{ .name }}" -ErrDomainFormat: "{{ .name }} domain format error" -ErrDefaultAlias: "default is a reserved code name, please use another code name" - -#ssl -ErrSSLCannotDelete: "The certificate {{ .name }} is being used by the website and cannot be removed" -ErrAccountCannotDelete: "The certificate associated with the account cannot be deleted" -ErrSSLApply: "The certificate continues to be signed successfully, but openresty reload fails, please check the configuration!" -ErrEmailIsExist: 'Email is already exist' -ErrSSLKeyNotFound: 'The private key file does not exist' -ErrSSLCertificateNotFound: 'The certificate file does not exist' -ErrSSLKeyFormat: 'Private key file verification error' -ErrSSLCertificateFormat: 'Certificate file format error, please use pem format' -ErrEabKidOrEabHmacKeyCannotBlank: 'EabKid or EabHmacKey cannot be empty' -ErrOpenrestyNotFound: 'Http mode requires Openresty to be installed first' -ApplySSLStart: 'Start applying for certificate, domain name [{{ .domain }}] application method [{{ .type }}] ' -dnsAccount: "DNS Automatic" -dnsManual: "DNS Manual" -http: "HTTP" -ApplySSLFailed: 'Application for [{{ .domain }}] certificate failed, {{.detail}} ' -ApplySSLSuccess: 'Application for [{{ .domain }}] certificate successful! ! ' -DNSAccountName: 'DNS account [{{ .name }}] manufacturer [{{.type}}]' -PushDirLog: 'Certificate pushed to directory [{{ .path }}] {{ .status }}' -ErrDeleteCAWithSSL: "There is an issued certificate under the current organization and cannot be deleted" -ErrDeleteWithPanelSSL: "Panel SSL configuration uses this certificate and cannot be deleted" -ErrDefaultCA: "The default organization cannot be deleted" -ApplyWebSiteSSLLog: "Start updating {{ .name }} website certificate" -ErrUpdateWebsiteSSL: "{{ .name }} website failed to update certificate: {{ .err }}" -ApplyWebSiteSSLSuccess: "Update website certificate successfully" - -#mysql -ErrUserIsExist: "The current user already exists. Please enter a new user" -ErrDatabaseIsExist: "The current database already exists. Please enter a new database" -ErrExecTimeOut: "SQL execution timed out, please check the database" -ErrRemoteExist: "The remote database already exists with that name, please modify it and try again" -ErrLocalExist: "The local database already exists with that name, please modify it and try again" - -#redis -ErrTypeOfRedis: "The recovery file type does not match the current persistence mode. Modify the file type and try again" - -#container -ErrInUsed: "{{ .detail }} is in use and cannot be deleted" -ErrObjectInUsed: "This object is in use and cannot be deleted" -ErrPortRules: "The number of ports does not match, please re-enter!" -ErrPgImagePull: "Image pull timeout. Please configure image acceleration or manually pull the postgres:16.0-alpine image and try again" - -#runtime -ErrDirNotFound: "The build folder does not exist! Please check file integrity!" -ErrFileNotExist: "{{ .detail }} file does not exist! Please check source file integrity!" -ErrImageBuildErr: "Image build failed" -ErrImageExist: "Image is already exist!" -ErrDelWithWebsite: "The operating environment has been associated with a website and cannot be deleted" -ErrRuntimeStart: "Failed to start" -ErrPackageJsonNotFound: "package.json file does not exist" -ErrScriptsNotFound: "No scripts configuration item was found in package.json" -ErrContainerNameNotFound: "Unable to get container name, please check .env file" -ErrNodeModulesNotFound: "The node_modules folder does not exist! Please edit the running environment or wait for the running environment to start successfully" - -#setting -ErrBackupInUsed: "The backup account is already being used in a cronjob and cannot be deleted." -ErrBackupCheck: "Backup account test connection failed {{ .err}}" -ErrOSSConn: "Unable to retrieve the latest version, please check if the server can connect to the external network." -ErrEntrance: "Security entrance information error. Please check and try again!" - -#tool -ErrConfigNotFound: "Configuration file does not exist" -ErrConfigParse: "Configuration file format error" -ErrConfigIsNull: "The configuration file is not allowed to be empty" -ErrConfigDirNotFound: "The running directory does not exist" -ErrConfigAlreadyExist: "A configuration file with the same name already exists" -ErrUserFindErr: "Failed to find user {{ .name }} {{ .err }}" - -#ssh -ErrFirewall: "No firewalld or ufw service is detected. Please check and try again!" - -#cronjob -ErrBashExecute: "Script execution error, please check the specific information in the task output text area." -ErrCutWebsiteLog: "{{ .name }} website log cutting failed, error {{ .err }}" -CutWebsiteLogSuccess: "{{ .name }} website log cut successfully, backup path {{ .path }}" - -#toolbox -ErrNotExistUser: "The current user does not exist. Please modify and retry!" -ErrBanAction: "Setting failed, the current {{ .name }} service is unavailable, please check and try again!" -ErrClamdscanNotFound: "The clamdscan command was not detected, please refer to the documentation to install it!" - -#waf -ErrScope: "Modification of this configuration is not supported" -ErrStateChange: "State modification failed" -ErrRuleExist: "Rule is Exist" -ErrRuleNotExist: "Rule is not Exist" -ErrParseIP: "IP format error" -ErrDefaultIP: "default is a reserved name, please change it to another name" -ErrGroupInUse: "The IP group is used by the black/white list and cannot be deleted" -ErrGroupExist: "IP group name already exists" -ErrIPRange: "Wrong IP range" -ErrIPExist: "IP is exit" - -#license -ErrLicense: "License format error, please check and try again!" -ErrLicenseCheck: "License verification failed, please check and try again!" -ErrLicenseSave: "Failed to save license information, error {{ .err }}, please try again!" -ErrLicenseSync: "Failed to sync license information, no license information detected in the database!" -ErrXpackNotFound: "This section is a professional edition feature, please import the license first in Panel Settings-License interface" -ErrXpackNotActive: "This section is a professional edition feature, please synchronize the license status first in Panel Settings-License interface" -ErrXpackOutOfDate: "The current license has expired, please re-import the license in Panel Settings-License interface" +ErrNoSuchHost: "Network connection failed" \ No newline at end of file diff --git a/core/i18n/lang/zh-Hant.yaml b/core/i18n/lang/zh-Hant.yaml index 56a8e2227..6c9d5019f 100644 --- a/core/i18n/lang/zh-Hant.yaml +++ b/core/i18n/lang/zh-Hant.yaml @@ -4,7 +4,7 @@ ErrInitialPassword: "原密碼錯誤" ErrInternalServer: "伺服器內部錯誤: {{ .detail }}" ErrRecordExist: "記錄已存在" ErrRecordNotFound: "記錄未找到" -ErrStructTransform: "類型轉換失敗: {{ .detail }}" +ErrTransform: "類型轉換失敗: {{ .detail }}" ErrNotLogin: "用戶未登入: {{ .detail }}" ErrPasswordExpired: "當前密碼已過期: {{ .detail }}" ErrNotSupportType: "系統暫不支持當前類型: {{ .detail }}" @@ -12,189 +12,12 @@ ErrNotSupportType: "系統暫不支持當前類型: {{ .detail }}" #common ErrNameIsExist: "名稱已存在" ErrDemoEnvironment: "演示伺服器,禁止此操作!" -ErrCmdTimeout: "指令執行超時!" -ErrCmdIllegal: "執行命令中存在不合法字符,請修改後重試!" -ErrPortExist: '{{ .port }} 埠已被 {{ .type }} [{{ .name }}] 佔用' -TYPE_APP: "應用" -TYPE_RUNTIME: "運作環境" -TYPE_DOMAIN: "網域名稱" -ErrTypePort: '埠 {{ .name }} 格式錯誤' -ErrTypePortRange: '連接埠範圍需要在 1-65535 之間' -Success: "成功" -Failed: "失敗" -SystemRestart: "系統重啟導致任務中斷" -ErrInvalidChar: "禁止使用非法字元" +ErrEntrance: "安全入口信息錯誤,請檢查後重試!" #app ErrPortInUsed: "{{ .detail }} 端口已被佔用!" -ErrAppLimit: "應用超出安裝數量限制" -ErrAppRequired: "請先安裝 {{ .detail }} 應用" -ErrNotInstall: "應用未安裝" -ErrPortInOtherApp: "{{ .port }} 端口已被應用 {{ .apps }} 佔用!" -ErrDbUserNotValid: "儲存資料庫,用戶名密碼不匹配!" -ErrDockerComposeNotValid: "docker-compose 文件格式錯誤" -ErrUpdateBuWebsite: '應用更新成功,但是網站配置文件修改失敗,請檢查配置!' -Err1PanelNetworkFailed: '默認容器網絡創建失敗!{{ .detail }}' -ErrFileParse: '應用 docker-compose 文件解析失敗!' -ErrInstallDirNotFound: '安裝目錄不存在' -AppStoreIsUpToDate: '應用商店已經是最新版本' -LocalAppVersionNull: '{{.name}} 應用未同步到版本!無法添加到應用列表' -LocalAppVersionErr: '{{.name}} 同步版本 {{.version}} 失敗!{{.err}}' -ErrFileNotFound: '{{.name}} 文件不存在' -ErrFileParseApp: '{{.name}} 文件解析失敗 {{.err}}' -ErrAppDirNull: '版本資料夾不存在' -LocalAppErr: "應用 {{.name}} 同步失敗!{{.err}}" -ErrContainerName: "容器名稱已存在" -ErrAppSystemRestart: "1Panel 重啟導致任務中斷" ErrCreateHttpClient: "創建HTTP請求失敗 {{.err}}" ErrHttpReqTimeOut: "請求超時 {{.err}}" ErrHttpReqFailed: "請求失敗 {{.err}}" ErrHttpReqNotFound: "文件不存在" -ErrNoSuchHost: "網路連接失敗" -ErrImagePullTimeOut: "鏡像拉取超時" -ErrContainerNotFound: '{{ .name }} 容器不存在' -ErrContainerMsg: '{{ .name }} 容器異常,具體請在容器頁面查看日誌' -ErrAppBackup: '{{ .name }} 應用備份失敗 err {{.err}}' -ErrImagePull: '{{ .name }} 鏡像拉取失敗 err {{.err}}' -ErrVersionTooLow: '當前 1Panel 版本過低,無法更新應用商店,請升級版本之後操作' -ErrAppNameExist: '應用名稱已存在' -AppStoreIsSyncing: '應用程式商店正在同步中,請稍後再試' -ErrGetCompose: "docker-compose.yml 檔案取得失敗!{{ .detail }}" -ErrAppWarn: "狀態異常,請查看日誌" -ErrAppParamKey: "參數 {{ .name }} 欄位異常" -ErrAppUpgrade: "應用程式 {{ .name }} 升級失敗 {{ .err }}" -AppRecover: "應用程式 {{ .name }} 回滾 " -PullImageStart: "開始拉取鏡像 {{ .name }}" -PullImageSuccess: "鏡像拉取成功" -UpgradeAppStart: "開始升級應用程式 {{ .name }}" -UpgradeAppSuccess: "應用程式 {{ .name }} 升級成功" - -#file -ErrFileCanNotRead: "此文件不支持預覽" -ErrFileToLarge: "文件超過10M,無法打開" -ErrPathNotFound: "目錄不存在" -ErrMovePathFailed: "目標路徑不能包含原路徑!" -ErrLinkPathNotFound: "目標路徑不存在!" -ErrFileIsExist: "文件或文件夾已存在!" -ErrFileUpload: "{{ .name }} 上傳文件失敗 {{ .detail}}" -ErrFileDownloadDir: "不支持下載文件夾" -ErrCmdNotFound: "{{ .name}} 命令不存在,請先在宿主機安裝此命令" -ErrSourcePathNotFound: "源目錄不存在" -ErrFavoriteExist: "已收藏此路徑" - -#website -ErrDomainIsExist: "域名已存在" -ErrAliasIsExist: "代號已存在" -ErrAppDelete: '其他網站使用此應用,無法刪除' -ErrGroupIsUsed: '分組正在使用中,無法刪除' -ErrBackupMatch: '該備份文件與當前網站部分數據不匹配: {{ .detail}}' -ErrBackupExist: '該備份文件對應部分原數據不存在: {{ .detail}}' -ErrPHPResource: '本地運行環境不支持切換!' -ErrPathPermission: 'index 目錄下偵測到非 1000:1000 權限資料夾,可能導致網站存取 Access denied 錯誤,請點擊上方儲存按鈕' -ErrDomainIsUsed: "域名已被網站【{{ .name }}】使用" -ErrDomainFormat: "{{ .name }} 域名格式不正確" -ErrDefaultAlias: "default 為保留代號,請使用其他代號" - -#ssl -ErrSSLCannotDelete: "{{ .name }} 證書正在被網站使用,無法刪除" -ErrAccountCannotDelete: "帳號關聯證書,無法刪除" -ErrSSLApply: "證書續簽成功,openresty reload失敗,請檢查配置!" -ErrEmailIsExist: '郵箱已存在' -ErrSSLKeyNotFound: '私鑰文件不存在' -ErrSSLCertificateNotFound: '證書文件不存在' -ErrSSLKeyFormat: '私鑰文件校驗錯誤' -ErrSSLCertificateFormat: '證書文件格式錯誤,請使用 pem 格式' -ErrEabKidOrEabHmacKeyCannotBlank: 'EabKid 或 EabHmacKey 不能為空' -ErrOpenrestyNotFound: 'Http 模式需要先安裝 Openresty' -ApplySSLStart: '開始申請憑證,網域 [{{ .domain }}] 申請方式 [{{ .type }}] ' -dnsAccount: "DNS 自動" -dnsManual: "DNS 手排" -http: "HTTP" -ApplySSLFailed: '申請 [{{ .domain }}] 憑證失敗, {{.detail}} ' -ApplySSLSuccess: '申請 [{{ .domain }}] 憑證成功! ! ' -DNSAccountName: 'DNS 帳號 [{{ .name }}] 廠商 [{{.type}}]' -PushDirLog: '憑證推送到目錄 [{{ .path }}] {{ .status }}' -ErrDeleteCAWithSSL: "目前機構下存在已簽發證書,無法刪除" -ErrDeleteWithPanelSSL: "面板 SSL 配置使用此證書,無法刪除" -ErrDefaultCA: "默認機構不能刪除" -ApplyWebSiteSSLLog: "開始更新 {{ .name }} 網站憑證" -ErrUpdateWebsiteSSL: "{{ .name }} 網站更新憑證失敗: {{ .err }}" -ApplyWebSiteSSLSuccess: "更新網站憑證成功" - - -#mysql -ErrUserIsExist: "當前用戶已存在,請重新輸入" -ErrDatabaseIsExist: "當前資料庫已存在,請重新輸入" -ErrExecTimeOut: "SQL 執行超時,請檢查數據庫" -ErrRemoteExist: "遠程數據庫已存在該名稱,請修改後重試" -ErrLocalExist: "本地數據庫已存在該名稱,請修改後重試" - -#redis -ErrTypeOfRedis: "恢復文件類型與當前持久化方式不符,請修改後重試" - -#container -ErrInUsed: "{{ .detail }} 正被使用,無法刪除" -ErrObjectInUsed: "該對象正被使用,無法刪除" -ErrPortRules: "端口數目不匹配,請重新輸入!" -ErrPgImagePull: "鏡像拉取超時,請配置鏡像加速或手動拉取 postgres:16.0-alpine 鏡像後重試" - -#runtime -ErrDirNotFound: "build 文件夾不存在!請檢查文件完整性!" -ErrFileNotExist: "{{ .detail }} 文件不存在!請檢查源文件完整性!" -ErrImageBuildErr: "鏡像 build 失敗" -ErrImageExist: "鏡像已存在!" -ErrDelWithWebsite: "運行環境已經關聯網站,無法刪除" -ErrRuntimeStart: "啟動失敗" -ErrPackageJsonNotFound: "package.json 文件不存在" -ErrScriptsNotFound: "沒有在 package.json 中找到 scripts 配置項" -ErrContainerNameNotFound: "無法取得容器名稱,請檢查 .env 文件" -ErrNodeModulesNotFound: "node_modules 文件夾不存在!請編輯運行環境或者等待運行環境啟動成功" - -#setting -ErrBackupInUsed: "該備份帳號已在計劃任務中使用,無法刪除" -ErrBackupCheck: "備份帳號測試連接失敗 {{ .err}}" -ErrOSSConn: "無法獲取最新版本,請確認伺服器是否能夠連接外部網路。" -ErrEntrance: "安全入口信息錯誤,請檢查後重試!" - -#tool -ErrConfigNotFound: "配置文件不存在" -ErrConfigParse: "配置文件格式有誤" -ErrConfigIsNull: "配置文件不允許為空" -ErrConfigDirNotFound: "運行目錄不存在" -ErrConfigAlreadyExist: "已存在同名配置文件" -ErrUserFindErr: "用戶 {{ .name }} 查找失敗 {{ .err }}" - -#ssh -ErrFirewall: "當前未檢測到系統 firewalld 或 ufw 服務,請檢查後重試!" - -#cronjob -ErrBashExecute: "腳本執行錯誤,請在任務輸出文本域中查看具體信息。" -ErrCutWebsiteLog: "{{ .name }} 網站日誌切割失敗,錯誤 {{ .err }}" -CutWebsiteLogSuccess: "{{ .name }} 網站日誌切割成功,備份路徑 {{ .path }}" - -#toolbox -ErrNotExistUser: "當前使用者不存在,請修改後重試!" -ErrBanAction: "設置失敗,當前 {{ .name }} 服務不可用,請檢查後重試!" -ErrClamdscanNotFound: "未偵測到 clamdscan 指令,請參考文件安裝!" - -#waf -ErrScope: "不支援修改此配置" -ErrStateChange: "狀態修改失敗" -ErrRuleExist: "規則已存在" -ErrRuleNotExist: "規則不存在" -ErrParseIP: "IP 格式錯誤" -ErrDefaultIP: "default 為保留名稱,請更換其他名稱" -ErrGroupInUse: "IP 群組被黑/白名單使用,無法刪除" -ErrGroupExist: "IP 群組名稱已存在" -ErrIPRange: "IP 範圍錯誤" -ErrIPExist: "IP 已存在" - - -#license -ErrLicense: "許可證格式錯誤,請檢查後重試!" -ErrLicenseCheck: "許可證校驗失敗,請檢查後重試!" -ErrLicenseSave: "許可證信息保存失敗,錯誤 {{ .err }}, 請重試!" -ErrLicenseSync: "許可證信息同步失敗,資料庫中未檢測到許可證信息!" -ErrXpackNotFound: "該部分為專業版功能,請先在 面板設置-許可證 界面導入許可證" -ErrXpackNotActive: "該部分為專業版功能,請先在 面板設置-許可證 界面同步許可證狀態" -ErrXpackOutOfDate: "當前許可證已過期,請重新在 面板設置-許可證 界面導入許可證" +ErrNoSuchHost: "網路連接失敗" \ No newline at end of file diff --git a/core/i18n/lang/zh.yaml b/core/i18n/lang/zh.yaml index eca156380..19383dd9b 100644 --- a/core/i18n/lang/zh.yaml +++ b/core/i18n/lang/zh.yaml @@ -4,199 +4,20 @@ ErrInitialPassword: "原密码错误" ErrInternalServer: "服务内部错误: {{ .detail }}" ErrRecordExist: "记录已存在" ErrRecordNotFound: "记录未能找到" -ErrStructTransform: "类型转换失败: {{ .detail }}" +ErrTransform: "类型转换失败: {{ .detail }}" ErrNotLogin: "用户未登录: {{ .detail }}" ErrPasswordExpired: "当前密码已过期: {{ .detail }}" ErrNotSupportType: "系统暂不支持当前类型: {{ .detail }}" #common -ErrNameIsExist: "名称已存在" ErrDemoEnvironment: "演示服务器,禁止此操作!" ErrCmdTimeout: "命令执行超时!" -ErrCmdIllegal: "执行命令中存在不合法字符,请修改后重试!" -ErrPortExist: '{{ .port }} 端口已被 {{ .type }} [{{ .name }}] 占用' -TYPE_APP: "应用" -TYPE_RUNTIME: "运行环境" -TYPE_DOMAIN: "域名" -ErrTypePort: '端口 {{ .name }} 格式错误' -ErrTypePortRange: '端口范围需要在 1-65535 之间' -Success: "成功" -Failed: "失败" -SystemRestart: "系统重启导致任务中断" +ErrEntrance: "安全入口信息错误,请检查后重试!" #app ErrPortInUsed: "{{ .detail }} 端口已被占用!" -ErrAppLimit: "应用超出安装数量限制" -ErrAppRequired: "请先安装 {{ .detail }} 应用" -ErrNotInstall: "应用未安装" -ErrPortInOtherApp: "{{ .port }} 端口已被应用 {{ .apps }} 占用!" -ErrDbUserNotValid: "存量数据库,用户名密码不匹配!" -ErrDockerComposeNotValid: "docker-compose 文件格式错误" -ErrUpdateBuWebsite: '应用更新成功,但是网站配置文件修改失败,请检查配置!' -Err1PanelNetworkFailed: '默认容器网络创建失败!{{ .detail }}' -ErrFileParse: '应用 docker-compose 文件解析失败!' -ErrInstallDirNotFound: '安装目录不存在' -AppStoreIsUpToDate: '应用商店已经是最新版本' -LocalAppVersionNull: '{{.name}} 应用未同步到版本!无法添加到应用列表' -LocalAppVersionErr: '{{.name}} 同步版本 {{.version}} 失败!{{.err}}' -ErrFileNotFound: '{{.name}} 文件不存在' -ErrFileParseApp: '{{.name}} 文件解析失败 {{.err}}' -ErrAppDirNull: '版本文件夹不存在' -LocalAppErr: "应用 {{.name}} 同步失败!{{.err}}" -ErrContainerName: "容器名称已存在" -ErrAppSystemRestart: "1Panel 重启导致任务终止" ErrCreateHttpClient: "创建HTTP请求失败 {{.err}}" ErrHttpReqTimeOut: "请求超时 {{.err}}" ErrHttpReqFailed: "请求失败 {{.err}}" ErrHttpReqNotFound: "文件不存在" -ErrNoSuchHost: "网络连接失败" -ErrImagePullTimeOut: '镜像拉取超时' -ErrContainerNotFound: '{{ .name }} 容器不存在' -ErrContainerMsg: '{{ .name }} 容器异常,具体请在容器页面查看日志' -ErrAppBackup: '{{ .name }} 应用备份失败 err {{.err}}' -ErrImagePull: '镜像拉取失败 {{.err}}' -ErrVersionTooLow: '当前 1Panel 版本过低,无法更新应用商店,请升级版本之后操作' -ErrAppNameExist: '应用名称已存在' -AppStoreIsSyncing: '应用商店正在同步中,请稍后再试' -ErrGetCompose: "docker-compose.yml 文件获取失败!{{ .detail }}" -ErrAppWarn: "状态异常,请查看日志" -ErrAppParamKey: "参数 {{ .name }} 字段异常" -ErrAppUpgrade: "应用 {{ .name }} 升级失败 {{ .err }}" -AppRecover: "应用 {{ .name }} 回滚 " -PullImageStart: "开始拉取镜像 {{ .name }}" -PullImageSuccess: "镜像拉取成功" -UpgradeAppStart: "开始升级应用 {{ .name }}" -UpgradeAppSuccess: "应用 {{ .name }} 升级成功" - -#file -ErrFileCanNotRead: "此文件不支持预览" -ErrFileToLarge: "文件超过10M,无法打开" -ErrPathNotFound: "目录不存在" -ErrMovePathFailed: "目标路径不能包含原路径!" -ErrLinkPathNotFound: "目标路径不存在!" -ErrFileIsExist: "文件或文件夹已存在!" -ErrFileUpload: "{{ .name }} 上传文件失败 {{ .detail}}" -ErrFileDownloadDir: "不支持下载文件夹" -ErrCmdNotFound: "{{ .name}} 命令不存在,请先在宿主机安装此命令" -ErrSourcePathNotFound: "源目录不存在" -ErrFavoriteExist: "已收藏此路径" -ErrInvalidChar: "禁止使用非法字符" - -#website -ErrDomainIsExist: "域名已存在" -ErrAliasIsExist: "代号已存在" -ErrAppDelete: '其他网站使用此应用,无法删除' -ErrGroupIsUsed: '分组正在使用中,无法删除' -ErrBackupMatch: '该备份文件与当前网站部分数据不匹配 {{ .detail}}' -ErrBackupExist: '该备份文件对应部分源数据不存在 {{ .detail}}' -ErrPHPResource: '本地运行环境不支持切换!' -ErrPathPermission: 'index 目录下检测到非 1000:1000 权限文件夹,可能导致网站访问 Access denied 错误,请点击上方保存按钮' -ErrDomainIsUsed: "域名已被网站【{{ .name }}】使用" -ErrDomainFormat: "{{ .name }} 域名格式不正确" -ErrDefaultAlias: "default 为保留代号,请使用其他代号" - -#ssl -ErrSSLCannotDelete: "{{ .name }} 证书正在被网站使用,无法删除" -ErrAccountCannotDelete: "账号关联证书,无法删除" -ErrSSLApply: "证书续签成功,openresty reload失败,请检查配置!" -ErrEmailIsExist: '邮箱已存在' -ErrSSLKeyNotFound: '私钥文件不存在' -ErrSSLCertificateNotFound: '证书文件不存在' -ErrSSLKeyFormat: '私钥文件校验失败' -ErrSSLCertificateFormat: '证书文件格式错误,请使用 pem 格式' -ErrEabKidOrEabHmacKeyCannotBlank: 'EabKid 或 EabHmacKey 不能为空' -ErrOpenrestyNotFound: 'Http 模式需要首先安装 Openresty' -ApplySSLStart: '开始申请证书,域名 [{{ .domain }}] 申请方式 [{{ .type }}] ' -dnsAccount: "DNS 自动" -dnsManual: "DNS 手动" -http: "HTTP" -ApplySSLFailed: '申请 [{{ .domain }}] 证书失败, {{.detail}} ' -ApplySSLSuccess: '申请 [{{ .domain }}] 证书成功!!' -DNSAccountName: 'DNS 账号 [{{ .name }}] 厂商 [{{.type}}]' -PushDirLog: '证书推送到目录 [{{ .path }}] {{ .status }}' -ErrDeleteCAWithSSL: "当前机构下存在已签发证书,无法删除" -ErrDeleteWithPanelSSL: "面板 SSL 配置使用此证书,无法删除" -ErrDefaultCA: "默认机构不能删除" -ApplyWebSiteSSLLog: "开始更新 {{ .name }} 网站证书" -ErrUpdateWebsiteSSL: "{{ .name }} 网站更新证书失败: {{ .err }}" -ApplyWebSiteSSLSuccess: "更新网站证书成功" -ErrExecShell: "执行脚本失败 {{ .err }}" -ExecShellStart: "开始执行脚本" -ExecShellSuccess: "脚本执行成功" - -#mysql -ErrUserIsExist: "当前用户已存在,请重新输入" -ErrDatabaseIsExist: "当前数据库已存在,请重新输入" -ErrExecTimeOut: "SQL 执行超时,请检查数据库" -ErrRemoteExist: "远程数据库已存在该名称,请修改后重试" -ErrLocalExist: "本地数据库已存在该名称,请修改后重试" - -#redis -ErrTypeOfRedis: "恢复文件类型与当前持久化方式不符,请修改后重试" - -#container -ErrInUsed: "{{ .detail }} 正被使用,无法删除" -ErrObjectInUsed: "该对象正被使用,无法删除" -ErrPortRules: "端口数目不匹配,请重新输入!" -ErrPgImagePull: "镜像拉取超时,请配置镜像加速或手动拉取 postgres:16.0-alpine 镜像后重试" - -#runtime -ErrDirNotFound: "build 文件夹不存在!请检查文件完整性!" -ErrFileNotExist: "{{ .detail }} 文件不存在!请检查源文件完整性!" -ErrImageBuildErr: "镜像 build 失败" -ErrImageExist: "镜像已存在!" -ErrDelWithWebsite: "运行环境已经关联网站,无法删除" -ErrRuntimeStart: "启动失败" -ErrPackageJsonNotFound: "package.json 文件不存在" -ErrScriptsNotFound: "没有在 package.json 中找到 scripts 配置项" -ErrContainerNameNotFound: "无法获取容器名称,请检查 .env 文件" -ErrNodeModulesNotFound: "node_modules 文件夹不存在!请编辑运行环境或者等待运行环境启动成功" - -#setting -ErrBackupInUsed: "该备份账号已在计划任务中使用,无法删除" -ErrBackupCheck: "备份账号测试连接失败 {{ .err}}" -ErrOSSConn: "无法获取最新版本,请确认服务器是否能够连接外部网络。" -ErrEntrance: "安全入口信息错误,请检查后重试!" - -#tool -ErrConfigNotFound: "配置文件不存在" -ErrConfigParse: "配置文件格式有误" -ErrConfigIsNull: "配置文件不允许为空" -ErrConfigDirNotFound: "运行目录不存在" -ErrConfigAlreadyExist: "已存在同名配置文件" -ErrUserFindErr: "用户 {{ .name }} 查找失败 {{ .err }}" - -#ssh -ErrFirewall: "当前未检测到系统 firewalld 或 ufw 服务,请检查后重试!" - -#cronjob -ErrBashExecute: "脚本执行错误,请在任务输出文本域中查看具体信息。" -ErrCutWebsiteLog: "{{ .name }} 网站日志切割失败,错误 {{ .err }}" -CutWebsiteLogSuccess: "{{ .name }} 网站日志切割成功,备份路径 {{ .path }}" - -#toolbox -ErrNotExistUser: "当前用户不存在,请修改后重试!" -ErrBanAction: "设置失败,当前 {{ .name }} 服务不可用,请检查后重试!" -ErrClamdscanNotFound: "未检测到 clamdscan 命令,请参考文档安装!" - -#waf -ErrScope: "不支持修改此配置" -ErrStateChange: "状态修改失败" -ErrRuleExist: "规则已存在" -ErrRuleNotExist: "规则不存在" -ErrParseIP: "IP 格式错误" -ErrDefaultIP: "default 为保留名称,请更换其他名称" -ErrGroupInUse: "IP 组被黑/白名单使用,无法删除" -ErrGroupExist: "IP 组名称已存在" -ErrIPRange: "IP 范围错误" -ErrIPExist: "IP 已存在" - -#license -ErrLicense: "许可证格式错误,请检查后重试!" -ErrLicenseCheck: "许可证校验失败,请检查后重试!" -ErrLicenseSave: "许可证信息保存失败,错误 {{ .err }},请重试!" -ErrLicenseSync: "许可证信息同步失败,数据库中未检测到许可证信息!" -ErrXpackNotFound: "该部分为专业版功能,请先在 面板设置-许可证 界面导入许可证" -ErrXpackNotActive: "该部分为专业版功能,请先在 面板设置-许可证 界面同步许可证状态" -ErrXpackOutOfDate: "当前许可证已过期,请重新在 面板设置-许可证 界面导入许可证" - +ErrNoSuchHost: "网络连接失败" \ No newline at end of file diff --git a/core/init/migration/migrate.go b/core/init/migration/migrate.go index ae28e8f44..1eb29b80f 100644 --- a/core/init/migration/migrate.go +++ b/core/init/migration/migrate.go @@ -9,7 +9,7 @@ import ( func Init() { m := gormigrate.New(global.DB, gormigrate.DefaultOptions, []*gormigrate.Migration{ - migrations.Init, + migrations.AddTable, migrations.InitSetting, }) if err := m.Migrate(); err != nil { diff --git a/core/init/migration/migrations/init.go b/core/init/migration/migrations/init.go index fd1944a7d..5285d20f9 100644 --- a/core/init/migration/migrations/init.go +++ b/core/init/migration/migrations/init.go @@ -12,8 +12,8 @@ import ( "gorm.io/gorm" ) -var Init = &gormigrate.Migration{ - ID: "20200809-add-table-operation-log", +var AddTable = &gormigrate.Migration{ + ID: "20240722-add-table", Migrate: func(tx *gorm.DB) error { return tx.AutoMigrate( &model.OperationLog{}, @@ -75,7 +75,7 @@ var InitSetting = &gormigrate.Migration{ if err := tx.Create(&model.Setting{Key: "PrsoxyPasswdKeep", Value: ""}).Error; err != nil { return err } - if err := tx.Create(&model.Setting{Key: "XpackHideMenu", Value: "{\"id\":\"1\",\"label\":\"/xpack\",\"isCheck\":true,\"title\":\"xpack.menu\",\"children\":[{\"id\":\"2\",\"title\":\"xpack.waf.name\",\"path\":\"/xpack/waf/dashboard\",\"label\":\"Dashboard\",\"isCheck\":true},{\"id\":\"3\",\"title\":\"xpack.tamper.tamper\",\"path\":\"/xpack/tamper\",\"label\":\"Tamper\",\"isCheck\":true},{\"id\":\"4\",\"title\":\"xpack.gpu.gpu\",\"path\":\"/xpack/gpu\",\"label\":\"GPU\",\"isCheck\":true},{\"id\":\"5\",\"title\":\"xpack.setting.setting\",\"path\":\"/xpack/setting\",\"label\":\"XSetting\",\"isCheck\":true}]}"}).Error; err != nil { + if err := tx.Create(&model.Setting{Key: "XpackHideMenu", Value: "{\"id\":\"1\",\"label\":\"/xpack\",\"isCheck\":true,\"title\":\"xpack.menu\",\"children\":[{\"id\":\"2\",\"title\":\"xpack.waf.name\",\"path\":\"/xpack/waf/dashboard\",\"label\":\"Dashboard\",\"isCheck\":true},{\"id\":\"3\",\"title\":\"xpack.tamper.tamper\",\"path\":\"/xpack/tamper\",\"label\":\"Tamper\",\"isCheck\":true},{\"id\":\"4\",\"title\":\"xpack.gpu.gpu\",\"path\":\"/xpack/gpu\",\"label\":\"GPU\",\"isCheck\":true},{\"id\":\"5\",\"title\":\"xpack.setting.setting\",\"path\":\"/xpack/setting\",\"label\":\"XSetting\",\"isCheck\":true},{\"id\":\"6\",\"title\":\"xpack.monitor.name\",\"path\":\"/xpack/monitor/dashboard\",\"label\":\"MonitorDashboard\",\"isCheck\":true},{\"id\":\"7\",\"title\":\"xpack.multihost\",\"path\":\"/xpack/multihost/manage\",\"label\":\"Multihost\",\"isCheck\":true}]}"}).Error; err != nil { return err } diff --git a/frontend/src/views/toolbox/clam/setting/index.vue b/frontend/src/views/toolbox/clam/setting/index.vue index 9e2f83f42..e4edaf784 100644 --- a/frontend/src/views/toolbox/clam/setting/index.vue +++ b/frontend/src/views/toolbox/clam/setting/index.vue @@ -57,7 +57,7 @@