diff --git a/agent/app/api/v2/website_ssl.go b/agent/app/api/v2/website_ssl.go index c46b0b1e5d43..d2ec38695612 100644 --- a/agent/app/api/v2/website_ssl.go +++ b/agent/app/api/v2/website_ssl.go @@ -2,6 +2,8 @@ package v2 import ( "github.com/1Panel-dev/1Panel/agent/app/model" + "io" + "mime/multipart" "net/http" "net/url" "reflect" @@ -217,6 +219,79 @@ func (b *BaseApi) UploadWebsiteSSL(c *gin.Context) { helper.Success(c) } +// @Tags Website SSL +// @Summary Upload SSL file +// @Accept multipart/form-data +// @Param type formData string true "type" +// @Param description formData string false "description" +// @Param sslID formData string false "sslID" +// @Param privateKeyFile formData file true "privateKeyFile" +// @Param certificateFile formData file true "certificateFile" +// @Success 200 +// @Security ApiKeyAuth +// @Security Timestamp +// @Router /websites/ssl/upload/file [post] +// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传 ssl 文件 [type]","formatEN":"Upload ssl file [type]"} +func (b *BaseApi) UploadSSLFile(c *gin.Context) { + var req request.WebsiteSSLFileUpload + + req.Type = c.PostForm("type") + req.Description = c.PostForm("description") + sslID := c.PostForm("sslID") + if sslID != "" { + req.SSLID, _ = strconv.ParseUint(sslID, 10, 64) + } + + privateKeyFile, err := c.FormFile("privateKeyFile") + if err != nil { + helper.InternalServer(c, err) + return + } + + certificateFile, err := c.FormFile("certificateFile") + if err != nil { + helper.InternalServer(c, err) + return + } + + privateKeyContent, err := readUploadedFile(privateKeyFile) + if err != nil { + helper.InternalServer(c, err) + return + } + + certificateContent, err := readUploadedFile(certificateFile) + if err != nil { + helper.InternalServer(c, err) + return + } + + uploadReq := request.WebsiteSSLUpload{ + Type: "paste", + PrivateKey: string(privateKeyContent), + Certificate: string(certificateContent), + Description: req.Description, + SSLID: uint(req.SSLID), + } + + if err := websiteSSLService.Upload(uploadReq); err != nil { + helper.InternalServer(c, err) + return + } + + helper.SuccessWithData(c, nil) +} + +func readUploadedFile(fileHeader *multipart.FileHeader) ([]byte, error) { + file, err := fileHeader.Open() + if err != nil { + return nil, err + } + defer file.Close() + + return io.ReadAll(file) +} + // @Tags Website SSL // @Summary Download SSL file // @Accept json diff --git a/agent/app/dto/request/website_ssl.go b/agent/app/dto/request/website_ssl.go index 96c5c4d250c2..bf1a7a7d1064 100644 --- a/agent/app/dto/request/website_ssl.go +++ b/agent/app/dto/request/website_ssl.go @@ -157,3 +157,9 @@ type WebsiteCAObtain struct { type WebsiteCARenew struct { SSLID uint `json:"SSLID" validate:"required"` } + +type WebsiteSSLFileUpload struct { + Type string `json:"type"` + Description string `json:"description"` + SSLID uint64 `json:"sslID"` +} diff --git a/agent/router/ro_website_ssl.go b/agent/router/ro_website_ssl.go index fcb194063097..420b7045d3df 100644 --- a/agent/router/ro_website_ssl.go +++ b/agent/router/ro_website_ssl.go @@ -24,5 +24,6 @@ func (a *WebsiteSSLRouter) InitRouter(Router *gin.RouterGroup) { groupRouter.POST("/obtain", baseApi.ApplyWebsiteSSL) groupRouter.POST("/download", baseApi.DownloadWebsiteSSL) groupRouter.POST("/import", baseApi.ImportMasterSSL) + groupRouter.POST("/upload/file", baseApi.UploadSSLFile) } } diff --git a/frontend/src/api/modules/website.ts b/frontend/src/api/modules/website.ts index b7d0b236a565..dcc1a3bb0886 100644 --- a/frontend/src/api/modules/website.ts +++ b/frontend/src/api/modules/website.ts @@ -242,6 +242,10 @@ export const uploadSSL = (req: Website.SSLUpload) => { return http.post(`/websites/ssl/upload`, req); }; +export const uploadSSLFile = (params: FormData) => { + return http.upload(`/websites/ssl/upload/file`, params, {}); +}; + export const searchCAs = (req: ReqPage) => { return http.post>(`/websites/ca/search`, req); }; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index c3c7b950d1b0..504a0035cb60 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -522,7 +522,6 @@ const message = { formatHelper: 'The current database character set is {0}, the character set inconsistency may cause recovery failure', - selectFile: 'Select file', dropHelper: 'You can drag and drop the uploaded file here or', clickHelper: 'click to upload', supportUpType: @@ -3440,7 +3439,6 @@ const message = { 'Will be displayed in the upper left corner of the management page when the menu is expanded (recommended image size: 185px*55px)', favicon: 'Website Icon', faviconHelper: 'Website icon (recommended image size: 16px*16px)', - reUpload: 'Choose File', setDefault: 'Restore Default', setHelper: 'The current settings will be saved. Do you want to continue?', setDefaultHelper: 'All panel settings will be restored to default. Do you want to continue?', diff --git a/frontend/src/lang/modules/es-es.ts b/frontend/src/lang/modules/es-es.ts index 7c6e5fc94083..e915ed3cab9a 100644 --- a/frontend/src/lang/modules/es-es.ts +++ b/frontend/src/lang/modules/es-es.ts @@ -526,7 +526,6 @@ const message = { skipVerify: 'Omitir la verificación de validez del certificado', formatHelper: 'El conjunto de caracteres actual de la base de datos es {0}, la inconsistencia de conjuntos puede causar errores al recuperar', - selectFile: 'Seleccionar archivo', dropHelper: 'Puede arrastrar y soltar el archivo aquí o', clickHelper: 'hacer clic para subir', supportUpType: @@ -3396,7 +3395,6 @@ const message = { 'Se mostrará arriba a la izquierda cuando el menú esté expandido (tamaño recomendado: 185px*55px)', favicon: 'Icono del sitio', faviconHelper: 'Icono del sitio (tamaño recomendado: 16px*16px)', - reUpload: 'Elegir archivo', setDefault: 'Restaurar por defecto', setHelper: 'Se guardará la configuración actual. ¿Continuar?', setDefaultHelper: 'Todas las configuraciones se restaurarán a valores por defecto. ¿Continuar?', diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index 43018376f15a..fbeb155cc1c2 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -510,7 +510,6 @@ const message = { skipVerify: '証明書の有効性チェックを無視します', formatHelper: '現在のデータベース文字セットは{0}です。文字セットの矛盾は回復の故障を引き起こす可能性があります', - selectFile: '[ファイル]を選択します', dropHelper: 'ここでアップロードされたファイルをドラッグアンドドロップするか、', clickHelper: 'クリックしてアップロードします', supportUpType: @@ -3326,7 +3325,6 @@ const message = { 'メニューが展開されている場合、管理ページの左上隅に表示されます(推奨画像サイズ:185px*55px)', favicon: 'ウェブサイトアイコン', faviconHelper: 'ウェブサイトアイコン(推奨画像サイズ:16px*16px)', - reUpload: 'ファイルを選択', setDefault: 'デフォルトに戻す', setHelper: '現在の設定が保存されます。続けますか?', setDefaultHelper: 'すべてのパネル設定がデフォルトに戻されます。続けますか?', diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index 7b8520b879f5..a02b774d928a 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -508,7 +508,6 @@ const message = { skipVerify: '인증서 유효성 검사 무시', formatHelper: '현재 데이터베이스 문자셋은 {0} 입니다. 문자셋 불일치로 인해 복구에 실패할 수 있습니다.', - selectFile: '파일 선택', dropHelper: '여기에 업로드한 파일을 드래그 앤 드롭하거나', clickHelper: '클릭하여 업로드', supportUpType: @@ -3269,7 +3268,6 @@ const message = { '메뉴가 확장되었을 때 관리 페이지의 왼쪽 상단에 표시됩니다 (권장 이미지 크기: 185px*55px)', favicon: '웹사이트 아이콘', faviconHelper: '웹사이트 아이콘 (권장 이미지 크기: 16px*16px)', - reUpload: '파일 선택', setDefault: '기본값 복원', setHelper: '현재 설정이 저장됩니다. 계속하시겠습니까?', setDefaultHelper: '모든 패널 설정이 기본값으로 복원됩니다. 계속하시겠습니까?', diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index ab75a47e86c0..b89533655d6d 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -522,7 +522,6 @@ const message = { formatHelper: 'Set aksara pangkalan data semasa adalah {0}, ketidakkonsistenan set aksara mungkin menyebabkan kegagalan pemulihan.', - selectFile: 'Pilih fail', dropHelper: 'Anda boleh seret dan lepaskan fail yang ingin dimuat naik di sini atau', clickHelper: 'klik untuk memuat naik', supportUpType: @@ -3390,7 +3389,6 @@ const message = { 'Akan dipaparkan di sudut kiri atas halaman pengurusan apabila menu diperluaskan (saiz imej yang disarankan: 185px*55px)', favicon: 'Ikon Laman Web', faviconHelper: 'Ikon laman web (saiz imej yang disarankan: 16px*16px)', - reUpload: 'Pilih Fail', setDefault: 'Pulihkan Tetapan Asal', setHelper: 'Tetapan semasa akan disimpan. Adakah anda ingin meneruskan?', setDefaultHelper: 'Semua tetapan panel akan dikembalikan ke asal. Adakah anda ingin meneruskan?', diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index 385510ffb259..c2eac50f8461 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -520,7 +520,6 @@ const message = { formatHelper: 'O conjunto de caracteres atual do banco de dados é {0}, a inconsistência no conjunto de caracteres pode causar falha na recuperação', - selectFile: 'Selecionar arquivo', dropHelper: 'Você pode arrastar e soltar o arquivo carregado aqui ou', clickHelper: 'clicar para fazer upload', supportUpType: @@ -3407,7 +3406,6 @@ const message = { 'Será exibido no canto superior esquerdo da página de gerenciamento quando o menu estiver expandido (tamanho recomendado da imagem: 185px*55px)', favicon: 'Ícone do Site', faviconHelper: 'Ícone do site (tamanho recomendado da imagem: 16px*16px)', - reUpload: 'Selecionar Arquivo', setDefault: 'Restaurar Padrão', setHelper: 'As configurações atuais serão salvas. Deseja continuar?', setDefaultHelper: 'Todas as configurações do painel serão restauradas para o padrão. Deseja continuar?', diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index bde73a4f9c67..c77353744604 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -3397,7 +3397,6 @@ const message = { 'Будет отображаться в верхнем левом углу страницы управления при развернутом меню (рекомендуемый размер изображения: 185px*55px)', favicon: 'Иконка Сайта', faviconHelper: 'Иконка сайта (рекомендуемый размер изображения: 16px*16px)', - reUpload: 'Выбрать Файл', setDefault: 'Восстановить По Умолчанию', setHelper: 'Текущие настройки будут сохранены. Вы хотите продолжить?', setDefaultHelper: 'Все настройки панели будут восстановлены по умолчанию. Вы хотите продолжить?', diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts index ee7011420504..4e95fbbc1656 100644 --- a/frontend/src/lang/modules/tr.ts +++ b/frontend/src/lang/modules/tr.ts @@ -528,7 +528,6 @@ const message = { skipVerify: 'Sertifika geçerlilik kontrolünü yoksay', formatHelper: 'Mevcut veritabanı karakter seti {0}, karakter seti tutarsızlığı kurtarma işleminin başarısız olmasına neden olabilir', - selectFile: 'Dosya seç', dropHelper: 'Yüklenen dosyayı buraya sürükleyip bırakabilir veya', clickHelper: 'yüklemek için tıklayın', supportUpType: @@ -3477,7 +3476,6 @@ const message = { 'Menü genişletildiğinde yönetim sayfasının sol üst köşesinde gösterilecektir (önerilen görüntü boyutu: 185px*55px)', favicon: 'Web Sitesi Simgesi', faviconHelper: 'Web sitesi simgesi (önerilen görüntü boyutu: 16px*16px)', - reUpload: 'Dosya Seç', setDefault: 'Varsayılana Geri Yükle', setHelper: 'Mevcut ayarlar kaydedilecek. Devam etmek istiyor musunuz?', setDefaultHelper: 'Tüm panel ayarları varsayılana geri yüklenecek. Devam etmek istiyor musunuz?', diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts index 6c97e9b300d1..427013744f59 100644 --- a/frontend/src/lang/modules/zh-Hant.ts +++ b/frontend/src/lang/modules/zh-Hant.ts @@ -504,7 +504,6 @@ const message = { skipVerify: '忽略校驗證書可用性檢測', formatHelper: '目前資料庫字元集為 {0},字元集不一致可能導致復原失敗', - selectFile: '選擇文件', dropHelper: '將上傳文件拖曳到此處,或者', clickHelper: '點擊上傳', supportUpType: @@ -3205,7 +3204,6 @@ const message = { logoWithTextHelper: '將會顯示在選單展開時管理頁面左上方 (建議圖片大小為: 185px*55px)', favicon: '網站圖示', faviconHelper: '網站圖示 (建議圖片大小為: 16px*16px)', - reUpload: '選擇文件', setDefault: '復原預設', setHelper: '即將儲存目前介面設定內容,是否繼續?', setDefaultHelper: '即將復原所有介面設定到初始狀態,是否繼續?', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 8a67844e5f5c..fa8ade5371e2 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -502,7 +502,6 @@ const message = { skipVerify: '忽略校验证书可用性检测', formatHelper: '当前数据库字符集为 {0},字符集不一致可能导致恢复失败', - selectFile: '选择文件', dropHelper: '将上传文件拖拽到此处,或者', clickHelper: '点击上传', supportUpType: @@ -3177,7 +3176,6 @@ const message = { logoWithTextHelper: '将会显示在菜单展开时管理页面左上方 (建议图片大小为: 185px*55px)', favicon: '网站图标', faviconHelper: '网站图标 (建议图片大小为: 16px*16px)', - reUpload: '选择文件', setHelper: '即将保存当前界面设置内容,是否继续?', setDefaultHelper: '即将恢复所有界面设置到初始状态,是否继续?', logoGroup: 'Logo', diff --git a/frontend/src/views/website/ssl/upload/index.vue b/frontend/src/views/website/ssl/upload/index.vue index ebfb2a6f6b65..6deced5bd3ee 100644 --- a/frontend/src/views/website/ssl/upload/index.vue +++ b/frontend/src/views/website/ssl/upload/index.vue @@ -5,6 +5,7 @@ +
@@ -31,6 +32,40 @@
+
+ + + + + + + + + + +
@@ -38,7 +73,7 @@