From f6b84d384e41c1c708d41160b2af9761d984f558 Mon Sep 17 00:00:00 2001 From: ssongliu <73214554+ssongliu@users.noreply.github.com> Date: Wed, 2 Aug 2023 22:36:37 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E8=B6=8A=E6=9D=83?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E6=96=87=E4=BB=B6=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20(#1813)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/v1/cronjob.go | 3 +- backend/app/api/v1/file.go | 22 ------ backend/app/api/v1/setting.go | 18 +++++ backend/app/service/cornjob.go | 24 +++---- backend/app/service/setting.go | 2 +- backend/router/ro_file.go | 1 - backend/router/ro_setting.go | 1 + cmd/server/docs/docs.go | 72 +++++-------------- cmd/server/docs/swagger.json | 72 +++++-------------- cmd/server/docs/swagger.yaml | 45 +++--------- frontend/src/api/modules/cronjob.ts | 7 +- frontend/src/api/modules/files.ts | 4 -- frontend/src/api/modules/setting.ts | 3 + frontend/src/views/cronjob/record/index.vue | 15 ++-- frontend/src/views/setting/safe/ssl/index.vue | 20 +++--- 15 files changed, 111 insertions(+), 198 deletions(-) diff --git a/backend/app/api/v1/cronjob.go b/backend/app/api/v1/cronjob.go index c75e6f338..0a1614150 100644 --- a/backend/app/api/v1/cronjob.go +++ b/backend/app/api/v1/cronjob.go @@ -246,7 +246,8 @@ func (b *BaseApi) TargetDownload(c *gin.Context) { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return } - helper.SuccessWithData(c, filePath) + + c.File(filePath) } // @Tags Cronjob diff --git a/backend/app/api/v1/file.go b/backend/app/api/v1/file.go index 1542a2c7b..20a234291 100644 --- a/backend/app/api/v1/file.go +++ b/backend/app/api/v1/file.go @@ -544,28 +544,6 @@ func (b *BaseApi) DownloadChunkFiles(c *gin.Context) { } } -// @Tags File -// @Summary Download file with path -// @Description 下载指定文件 -// @Accept json -// @Param request body dto.FilePath true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /files/download/bypath [post] -// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载文件 [path]","formatEN":"Download file [path]"} -func (b *BaseApi) DownloadFile(c *gin.Context) { - var req dto.FilePath - if err := c.ShouldBindJSON(&req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) - return - } - if err := global.VALID.Struct(req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) - return - } - c.File(req.Path) -} - // @Tags File // @Summary Load file size // @Description 获取文件夹大小 diff --git a/backend/app/api/v1/setting.go b/backend/app/api/v1/setting.go index e6a867a31..4f5a62b3d 100644 --- a/backend/app/api/v1/setting.go +++ b/backend/app/api/v1/setting.go @@ -3,6 +3,8 @@ package v1 import ( "errors" "fmt" + "os" + "path" "strconv" "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" @@ -134,6 +136,22 @@ func (b *BaseApi) LoadFromCert(c *gin.Context) { 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 Update system port // @Description 更新系统端口 diff --git a/backend/app/service/cornjob.go b/backend/app/service/cornjob.go index a0200f7d6..8e6eb89de 100644 --- a/backend/app/service/cornjob.go +++ b/backend/app/service/cornjob.go @@ -141,12 +141,8 @@ func (u *CronjobService) Download(down dto.CronjobDownload) (string, error) { if record.ID == 0 { return "", constant.ErrRecordNotFound } - cronjob, _ := cronjobRepo.Get(commonRepo.WithByID(record.CronjobID)) - if cronjob.ID == 0 { - return "", constant.ErrRecordNotFound - } backup, _ := backupRepo.Get(commonRepo.WithByID(down.BackupAccountID)) - if cronjob.ID == 0 { + if backup.ID == 0 { return "", constant.ErrRecordNotFound } if backup.Type == "LOCAL" || record.FromLocal { @@ -155,15 +151,17 @@ func (u *CronjobService) Download(down dto.CronjobDownload) (string, error) { } return record.File, nil } - client, err := NewIBackupService().NewClient(&backup) - if err != nil { - return "", err - } tempPath := fmt.Sprintf("%s/download/%s", constant.DataDir, record.File) - _ = os.MkdirAll(path.Dir(tempPath), os.ModePerm) - isOK, err := client.Download(record.File, tempPath) - if !isOK || err != nil { - return "", err + if _, err := os.Stat(tempPath); err != nil && os.IsNotExist(err) { + client, err := NewIBackupService().NewClient(&backup) + if err != nil { + return "", err + } + _ = os.MkdirAll(path.Dir(tempPath), os.ModePerm) + isOK, err := client.Download(record.File, tempPath) + if !isOK || err != nil { + return "", err + } } return tempPath, nil } diff --git a/backend/app/service/setting.go b/backend/app/service/setting.go index dc3764e2b..37cfeee95 100644 --- a/backend/app/service/setting.go +++ b/backend/app/service/setting.go @@ -370,7 +370,7 @@ func loadInfoFromCert() (*dto.SSLInfo, error) { return &dto.SSLInfo{ Domain: strings.Join(domains, ","), Timeout: certObj.NotAfter.Format("2006-01-02 15:04:05"), - RootPath: global.CONF.System.BaseDir + "/1panel/secret/server.crt", + RootPath: path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt"), }, nil } diff --git a/backend/router/ro_file.go b/backend/router/ro_file.go index fafa0fbc5..a57509851 100644 --- a/backend/router/ro_file.go +++ b/backend/router/ro_file.go @@ -33,7 +33,6 @@ func (f *FileRouter) InitFileRouter(Router *gin.RouterGroup) { fileRouter.POST("/wget", baseApi.WgetFile) fileRouter.POST("/move", baseApi.MoveFile) fileRouter.GET("/download", baseApi.Download) - fileRouter.POST("/download/bypath", baseApi.DownloadFile) fileRouter.POST("/chunkdownload", baseApi.DownloadChunkFiles) fileRouter.POST("/size", baseApi.Size) fileRouter.GET("/ws", baseApi.Ws) diff --git a/backend/router/ro_setting.go b/backend/router/ro_setting.go index ebaadca69..3736c09f4 100644 --- a/backend/router/ro_setting.go +++ b/backend/router/ro_setting.go @@ -25,6 +25,7 @@ func (s *SettingRouter) InitSettingRouter(Router *gin.RouterGroup) { 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.GET("/time/option", baseApi.LoadTimeZone) settingRouter.POST("/time/sync", baseApi.SyncTime) diff --git a/cmd/server/docs/docs.go b/cmd/server/docs/docs.go index 441f83719..01262f069 100644 --- a/cmd/server/docs/docs.go +++ b/cmd/server/docs/docs.go @@ -5093,48 +5093,6 @@ const docTemplate = `{ } } }, - "/files/download/bypath": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "下载指定文件", - "consumes": [ - "application/json" - ], - "tags": [ - "File" - ], - "summary": "Download file with path", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/dto.FilePath" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - }, - "x-panel-log": { - "BeforeFuntions": [], - "bodyKeys": [ - "path" - ], - "formatEN": "Download file [path]", - "formatZH": "下载文件 [path]", - "paramKeys": [] - } - } - }, "/files/mode": { "post": { "security": [ @@ -8823,6 +8781,25 @@ const docTemplate = `{ } } }, + "/settings/ssl/download": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "下载证书", + "tags": [ + "System Setting" + ], + "summary": "Download system cert", + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/settings/ssl/info": { "get": { "security": [ @@ -12520,17 +12497,6 @@ const docTemplate = `{ } } }, - "dto.FilePath": { - "type": "object", - "required": [ - "path" - ], - "properties": { - "path": { - "type": "string" - } - } - }, "dto.FirewallBaseInfo": { "type": "object", "properties": { diff --git a/cmd/server/docs/swagger.json b/cmd/server/docs/swagger.json index f0f846eca..7b5b5b8d7 100644 --- a/cmd/server/docs/swagger.json +++ b/cmd/server/docs/swagger.json @@ -5086,48 +5086,6 @@ } } }, - "/files/download/bypath": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "下载指定文件", - "consumes": [ - "application/json" - ], - "tags": [ - "File" - ], - "summary": "Download file with path", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/dto.FilePath" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - }, - "x-panel-log": { - "BeforeFuntions": [], - "bodyKeys": [ - "path" - ], - "formatEN": "Download file [path]", - "formatZH": "下载文件 [path]", - "paramKeys": [] - } - } - }, "/files/mode": { "post": { "security": [ @@ -8816,6 +8774,25 @@ } } }, + "/settings/ssl/download": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "下载证书", + "tags": [ + "System Setting" + ], + "summary": "Download system cert", + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/settings/ssl/info": { "get": { "security": [ @@ -12513,17 +12490,6 @@ } } }, - "dto.FilePath": { - "type": "object", - "required": [ - "path" - ], - "properties": { - "path": { - "type": "string" - } - } - }, "dto.FirewallBaseInfo": { "type": "object", "properties": { diff --git a/cmd/server/docs/swagger.yaml b/cmd/server/docs/swagger.yaml index 1d9c4d884..bcc255267 100644 --- a/cmd/server/docs/swagger.yaml +++ b/cmd/server/docs/swagger.yaml @@ -747,13 +747,6 @@ definitions: - fileName - source type: object - dto.FilePath: - properties: - path: - type: string - required: - - path - type: object dto.FirewallBaseInfo: properties: name: @@ -7084,33 +7077,6 @@ paths: formatEN: Download file [name] formatZH: 下载文件 [name] paramKeys: [] - /files/download/bypath: - post: - consumes: - - application/json - description: 下载指定文件 - parameters: - - description: request - in: body - name: request - required: true - schema: - $ref: '#/definitions/dto.FilePath' - responses: - "200": - description: OK - security: - - ApiKeyAuth: [] - summary: Download file with path - tags: - - File - x-panel-log: - BeforeFuntions: [] - bodyKeys: - - path - formatEN: Download file [path] - formatZH: 下载文件 [path] - paramKeys: [] /files/mode: post: consumes: @@ -9454,6 +9420,17 @@ paths: summary: Page system snapshot tags: - System Setting + /settings/ssl/download: + post: + description: 下载证书 + responses: + "200": + description: OK + security: + - ApiKeyAuth: [] + summary: Download system cert + tags: + - System Setting /settings/ssl/info: get: description: 获取证书信息 diff --git a/frontend/src/api/modules/cronjob.ts b/frontend/src/api/modules/cronjob.ts index da99dc4ba..df16e99d6 100644 --- a/frontend/src/api/modules/cronjob.ts +++ b/frontend/src/api/modules/cronjob.ts @@ -38,8 +38,11 @@ export const updateStatus = (params: Cronjob.UpdateStatus) => { return http.post(`cronjobs/status`, params); }; -export const download = (params: Cronjob.Download) => { - return http.post(`cronjobs/download`, params); +export const downloadRecordCheck = (params: Cronjob.Download) => { + return http.post(`cronjobs/download`, params, 40000); +}; +export const downloadRecord = (params: Cronjob.Download) => { + return http.download(`cronjobs/download`, params, { responseType: 'blob', timeout: 40000 }); }; export const handleOnce = (id: number) => { diff --git a/frontend/src/api/modules/files.ts b/frontend/src/api/modules/files.ts index 81a5baa17..a33a37603 100644 --- a/frontend/src/api/modules/files.ts +++ b/frontend/src/api/modules/files.ts @@ -79,10 +79,6 @@ export const DownloadFile = (params: File.FileDownload) => { return http.download('files/download', params, { responseType: 'blob', timeout: 20000 }); }; -export const DownloadByPath = (path: string) => { - return http.download('files/download/bypath', { path: path }, { responseType: 'blob', timeout: 40000 }); -}; - export const ComputeDirSize = (params: File.DirSizeReq) => { return http.post('files/size', params); }; diff --git a/frontend/src/api/modules/setting.ts b/frontend/src/api/modules/setting.ts index fda1d9a35..2a6e1dd6b 100644 --- a/frontend/src/api/modules/setting.ts +++ b/frontend/src/api/modules/setting.ts @@ -30,6 +30,9 @@ export const updateSSL = (param: Setting.SSLUpdate) => { export const loadSSLInfo = () => { return http.get(`/settings/ssl/info`); }; +export const downloadSSL = () => { + return http.download(`settings/ssl/download`); +}; export const handleExpired = (param: Setting.PasswordUpdate) => { return http.post(`/settings/expired/handle`, param); diff --git a/frontend/src/views/cronjob/record/index.vue b/frontend/src/views/cronjob/record/index.vue index 75cec26ee..55af27c44 100644 --- a/frontend/src/views/cronjob/record/index.vue +++ b/frontend/src/views/cronjob/record/index.vue @@ -358,11 +358,18 @@ import { onBeforeUnmount, reactive, ref } from 'vue'; import { Cronjob } from '@/api/interface/cronjob'; import { loadZero } from '@/utils/util'; -import { searchRecords, download, handleOnce, updateStatus, cleanRecords, getRecordLog } from '@/api/modules/cronjob'; +import { + searchRecords, + downloadRecord, + handleOnce, + updateStatus, + cleanRecords, + getRecordLog, + downloadRecordCheck, +} from '@/api/modules/cronjob'; import { dateFormat } from '@/utils/util'; import i18n from '@/lang'; import { ElMessageBox } from 'element-plus'; -import { DownloadByPath } from '@/api/modules/files'; import { Codemirror } from 'vue-codemirror'; import { javascript } from '@codemirror/lang-javascript'; import { oneDark } from '@codemirror/theme-one-dark'; @@ -562,8 +569,8 @@ const onDownload = async (record: any, backupID: number) => { recordID: record.id, backupAccountID: backupID, }; - await download(params).then(async (res) => { - const file = await DownloadByPath(res.data); + await downloadRecordCheck(params).then(async () => { + const file = await downloadRecord(params); const downloadUrl = window.URL.createObjectURL(new Blob([file])); const a = document.createElement('a'); a.style.display = 'none'; diff --git a/frontend/src/views/setting/safe/ssl/index.vue b/frontend/src/views/setting/safe/ssl/index.vue index a015a3694..e195b5246 100644 --- a/frontend/src/views/setting/safe/ssl/index.vue +++ b/frontend/src/views/setting/safe/ssl/index.vue @@ -107,8 +107,7 @@ import { ListSSL } from '@/api/modules/website'; import { reactive, ref } from 'vue'; import i18n from '@/lang'; import { MsgSuccess } from '@/utils/message'; -import { updateSSL } from '@/api/modules/setting'; -import { DownloadByPath } from '@/api/modules/files'; +import { downloadSSL, updateSSL } from '@/api/modules/setting'; import { Rules } from '@/global/form-rules'; import { ElMessageBox, FormInstance } from 'element-plus'; import { Setting } from '@/api/interface/setting'; @@ -178,14 +177,15 @@ const changeSSl = (sslid: number) => { }; const onDownload = async () => { - const file = await DownloadByPath(form.rootPath); - const downloadUrl = window.URL.createObjectURL(new Blob([file])); - const a = document.createElement('a'); - a.style.display = 'none'; - a.href = downloadUrl; - a.download = 'server.crt'; - const event = new MouseEvent('click'); - a.dispatchEvent(event); + await downloadSSL().then(async (file) => { + const downloadUrl = window.URL.createObjectURL(new Blob([file])); + const a = document.createElement('a'); + a.style.display = 'none'; + a.href = downloadUrl; + a.download = 'server.crt'; + const event = new MouseEvent('click'); + a.dispatchEvent(event); + }); }; const onSaveSSL = async (formEl: FormInstance | undefined) => {