瀏覽代碼

feat: revoke certificate #293

Jacky 3 周之前
父節點
當前提交
c073801794
共有 35 個文件被更改,包括 1785 次插入550 次删除
  1. 1 1
      README-zh_CN.md
  2. 1 1
      README-zh_TW.md
  3. 1 1
      README.md
  4. 2 0
      api/certificate/certificate.go
  5. 3 0
      api/certificate/issue.go
  6. 122 0
      api/certificate/revoke.go
  7. 1 0
      api/certificate/router.go
  8. 1 0
      app/src/api/auto_cert.ts
  9. 1 0
      app/src/api/cert.ts
  10. 114 44
      app/src/language/ar/app.po
  11. 114 44
      app/src/language/de_DE/app.po
  12. 111 44
      app/src/language/en/app.po
  13. 114 44
      app/src/language/es/app.po
  14. 114 44
      app/src/language/fr_FR/app.po
  15. 111 44
      app/src/language/ko_KR/app.po
  16. 99 44
      app/src/language/messages.pot
  17. 114 44
      app/src/language/ru_RU/app.po
  18. 114 44
      app/src/language/tr_TR/app.po
  19. 111 44
      app/src/language/vi_VN/app.po
  20. 106 45
      app/src/language/zh_CN/app.po
  21. 123 50
      app/src/language/zh_TW/app.po
  22. 2 2
      app/src/routes/modules/certificates.ts
  23. 13 2
      app/src/views/certificate/CertificateList/Certificate.vue
  24. 0 0
      app/src/views/certificate/components/ACMEUserSelector.vue
  25. 3 1
      app/src/views/certificate/components/CertificateEditor.vue
  26. 126 0
      app/src/views/certificate/components/RemoveCert.vue
  27. 0 0
      app/src/views/certificate/components/RenewCert.vue
  28. 0 0
      app/src/views/certificate/components/WildcardCertificate.vue
  29. 9 1
      app/src/views/site/cert/components/AutoCertStepOne.vue
  30. 1 0
      internal/cert/auto_cert.go
  31. 34 0
      internal/cert/issue.go
  32. 8 5
      internal/cert/payload.go
  33. 105 0
      internal/cert/revoke.go
  34. 1 0
      model/cert.go
  35. 5 1
      query/certs.gen.go

+ 1 - 1
README-zh_CN.md

@@ -75,7 +75,7 @@ Nginx 网络管理界面,由  [0xJacky](https://jackyu.cn/) 与 [Hintay](https
 - 在线查看服务器 CPU、内存、系统负载、磁盘使用率等指标
 - 配置修改后会自动备份,可以对比任意版本或恢复到任意版本
 - 支持镜像操作到多个集群节点,轻松管理多服务器环境
-- 导出加密的 Nginx/NginxUI 配置,方便快速部署和恢复到新环境
+- 导出加密的 Nginx / Nginx UI 配置,方便快速部署和恢复到新环境
 - 增强版在线 ChatGPT 助手,支持多种模型,包括显示 Deepseek-R1 的思考链,帮助您更好地理解和优化配置
 - 一键申请和自动续签 Let's encrypt 证书
 - 在线编辑 Nginx 配置文件,编辑器支持 Nginx 配置语法高亮

+ 1 - 1
README-zh_TW.md

@@ -77,7 +77,7 @@ Nginx 網路管理介面,由 [0xJacky](https://jackyu.cn/) 與 [Hintay](https:
 - 線上檢視伺服器 CPU、記憶體、系統負載、磁碟使用率等指標
 - 配置修改後會自動備份,可以對比任意版本或恢復到任意版本
 - 支援鏡像操作到多個集群節點,輕鬆管理多伺服器環境
-- 導出加密的 Nginx/NginxUI 配置,方便快速部署和恢復到新環境
+- 導出加密的 Nginx / Nginx UI 配置,方便快速部署和恢復到新環境
 - 增強版線上 ChatGPT 助手,支援多種模型,包括顯示 Deepseek-R1 的思考鏈,幫助您更好地理解和優化配置
 - 一鍵申請和自動續簽 Let's encrypt 憑證
 - 線上編輯 Nginx 設定檔,編輯器支援 Nginx 設定語法醒目提示

+ 1 - 1
README.md

@@ -92,7 +92,7 @@ URL:[https://demo.nginxui.com](https://demo.nginxui.com)
 - Online statistics for server indicators such as CPU usage, memory usage, load average, and disk usage.
 - Automatic configuration backup after changes, with version comparison and restore capabilities
 - Cluster management supporting mirroring operations to multiple nodes, making multi-server environments easy to manage
-- Export encrypted Nginx/NginxUI configurations for quick deployment and recovery to new environments
+- Export encrypted Nginx / Nginx UI configurations for quick deployment and recovery to new environments
 - Enhanced online ChatGPT assistant supporting multiple models, including Deepseek-R1's chain-of-thought display to help you better understand and optimize configurations
 - One-click deployment and automatic renewal Let's Encrypt certificates.
 - Online editing websites configurations with our self-designed **NgxConfigEditor** which is a user-friendly block editor for nginx configurations or **Ace Code Editor** which supports highlighting nginx configuration syntax.

+ 2 - 0
api/certificate/certificate.go

@@ -92,6 +92,7 @@ type certJson struct {
 	DnsCredentialID       uint64             `json:"dns_credential_id"`
 	ACMEUserID            uint64             `json:"acme_user_id"`
 	SyncNodeIds           []uint64           `json:"sync_node_ids"`
+	RevokeOld             bool               `json:"revoke_old"`
 }
 
 func AddCert(c *gin.Context) {
@@ -192,6 +193,7 @@ func ModifyCert(c *gin.Context) {
 		DnsCredentialID:       json.DnsCredentialID,
 		ACMEUserID:            json.ACMEUserID,
 		SyncNodeIds:           json.SyncNodeIds,
+		RevokeOld:             json.RevokeOld,
 	}
 
 	content := &cert.Content{

+ 3 - 0
api/certificate/issue.go

@@ -82,6 +82,8 @@ func IssueCert(c *gin.Context) {
 		return
 	}
 
+	payload.CertID = certModel.ID
+
 	if certModel.SSLCertificatePath != "" {
 		certInfo, _ := cert.GetCertInfo(certModel.SSLCertificatePath)
 		if certInfo != nil {
@@ -130,6 +132,7 @@ func IssueCert(c *gin.Context) {
 			MustStaple:              payload.MustStaple,
 			LegoDisableCNAMESupport: payload.LegoDisableCNAMESupport,
 			Log:                     log.ToString(),
+			RevokeOld:               payload.RevokeOld,
 		})).FirstOrCreate()
 	if err != nil {
 		logger.Error(err)

+ 122 - 0
api/certificate/revoke.go

@@ -0,0 +1,122 @@
+package certificate
+
+import (
+	"net/http"
+
+	"github.com/0xJacky/Nginx-UI/internal/cert"
+	"github.com/0xJacky/Nginx-UI/query"
+	"github.com/gin-gonic/gin"
+	"github.com/gorilla/websocket"
+	"github.com/spf13/cast"
+	"github.com/uozi-tech/cosy/logger"
+)
+
+type RevokeCertResponse struct {
+	Status  string `json:"status"`
+	Message string `json:"message"`
+}
+
+func handleRevokeCertLogChan(conn *websocket.Conn, logChan chan string) {
+	defer func() {
+		if err := recover(); err != nil {
+			logger.Error(err)
+		}
+	}()
+
+	for logString := range logChan {
+		err := conn.WriteJSON(RevokeCertResponse{
+			Status:  Info,
+			Message: logString,
+		})
+		if err != nil {
+			logger.Error(err)
+			return
+		}
+	}
+}
+
+// RevokeCert handles certificate revocation through websocket connection
+func RevokeCert(c *gin.Context) {
+	id := cast.ToUint64(c.Param("id"))
+
+	var upGrader = websocket.Upgrader{
+		CheckOrigin: func(r *http.Request) bool {
+			return true
+		},
+	}
+
+	// upgrade http to websocket
+	ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
+	if err != nil {
+		logger.Error(err)
+		return
+	}
+
+	defer func(ws *websocket.Conn) {
+		_ = ws.Close()
+	}(ws)
+
+	// Get certificate from database
+	certQuery := query.Cert
+	certModel, err := certQuery.FirstByID(id)
+	if err != nil {
+		logger.Error(err)
+		_ = ws.WriteJSON(RevokeCertResponse{
+			Status:  Error,
+			Message: "Certificate not found: " + err.Error(),
+		})
+		return
+	}
+
+	// Create payload for revocation
+	payload := &cert.ConfigPayload{
+		CertID:          id,
+		ServerName:      certModel.Domains,
+		ChallengeMethod: certModel.ChallengeMethod,
+		DNSCredentialID: certModel.DnsCredentialID,
+		ACMEUserID:      certModel.ACMEUserID,
+		KeyType:         certModel.KeyType,
+		Resource:        certModel.Resource,
+	}
+
+	logChan := make(chan string, 1)
+	errChan := make(chan error, 1)
+
+	go cert.RevokeCert(payload, logChan, errChan)
+
+	go handleRevokeCertLogChan(ws, logChan)
+
+	// block, until errChan closes
+	for err = range errChan {
+		logger.Error(err)
+		err = ws.WriteJSON(RevokeCertResponse{
+			Status:  Error,
+			Message: err.Error(),
+		})
+		if err != nil {
+			logger.Error(err)
+			return
+		}
+		return
+	}
+
+	// Update certificate status in database
+	err = certModel.Remove()
+	if err != nil {
+		logger.Error(err)
+		_ = ws.WriteJSON(RevokeCertResponse{
+			Status:  Error,
+			Message: "Failed to delete certificate from database: " + err.Error(),
+		})
+		return
+	}
+
+	err = ws.WriteJSON(RevokeCertResponse{
+		Status:  Success,
+		Message: "Certificate revoked successfully",
+	})
+	if err != nil {
+		logger.Error(err)
+		return
+	}
+}

+ 1 - 0
api/certificate/router.go

@@ -23,6 +23,7 @@ func InitCertificateRouter(r *gin.RouterGroup) {
 
 func InitCertificateWebSocketRouter(r *gin.RouterGroup) {
 	r.GET("domain/:name/cert", IssueCert)
+	r.GET("certs/:id/revoke", RevokeCert)
 }
 
 func InitAcmeUserRouter(r *gin.RouterGroup) {

+ 1 - 0
app/src/api/auto_cert.ts

@@ -26,6 +26,7 @@ export interface AutoCertOptions {
   provider?: string
   must_staple?: boolean
   lego_disable_cname_support?: boolean
+  revoke_old?: boolean
 }
 
 const auto_cert = {

+ 1 - 0
app/src/api/cert.ts

@@ -22,6 +22,7 @@ export interface Cert extends ModelBase {
   log: string
   certificate_info: CertificateInfo
   sync_node_ids: number[]
+  revoke_old: boolean
 }
 
 export interface CertificateInfo {

+ 114 - 44
app/src/language/ar/app.po

@@ -35,7 +35,7 @@ msgid "Access Logs"
 msgstr "سجلات الدخول"
 
 #: src/routes/modules/certificates.ts:20 src/views/certificate/ACMEUser.vue:113
-#: src/views/certificate/ACMEUserSelector.vue:85
+#: src/views/certificate/components/ACMEUserSelector.vue:85
 msgid "ACME User"
 msgstr "مستخدم ACME"
 
@@ -49,7 +49,7 @@ msgstr "مستخدم ACME"
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
 #: src/views/preference/components/ExternalNotify/columns.ts:46
-#: src/views/site/site_list/columns.tsx:117 src/views/stream/StreamList.vue:74
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/StreamList.vue:74
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "إجراء"
@@ -281,7 +281,7 @@ msgstr ""
 msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:255
+#: src/views/certificate/components/CertificateEditor.vue:257
 #: src/views/config/ConfigEditor.vue:262 src/views/config/ConfigList.vue:112
 #: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:285
@@ -465,6 +465,12 @@ msgstr "خطأ في مزامنة الشهادة"
 msgid "Certificate path is empty"
 msgstr "نماذج التكوين"
 
+#: src/views/certificate/components/RemoveCert.vue:41
+#: src/views/certificate/components/RemoveCert.vue:61
+#, fuzzy
+msgid "Certificate removed successfully"
+msgstr "تم المسح بنجاح"
+
 #: src/views/preference/CertSettings.vue:27
 msgid "Certificate Renewal Interval"
 msgstr "الفاصل الزمني لتجديد الشهادة"
@@ -474,7 +480,7 @@ msgstr "الفاصل الزمني لتجديد الشهادة"
 msgid "Certificate renewed successfully"
 msgstr "تم المسح بنجاح"
 
-#: src/views/certificate/CertificateEditor.vue:128
+#: src/views/certificate/components/CertificateEditor.vue:128
 #: src/views/site/cert/Cert.vue:60
 msgid "Certificate Status"
 msgid_plural "Certificates Status"
@@ -486,7 +492,7 @@ msgstr[4] "حالة الشهادات"
 msgstr[5] "حالة الشهادة"
 
 #: src/routes/modules/certificates.ts:11
-#: src/views/certificate/CertificateList/Certificate.vue:13
+#: src/views/certificate/CertificateList/Certificate.vue:14
 msgid "Certificates"
 msgstr "شهادات"
 
@@ -788,6 +794,7 @@ msgstr "وصف"
 
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:21
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
+#: src/views/certificate/components/RemoveCert.vue:87
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
 #: src/views/site/site_list/SiteList.vue:176
@@ -795,6 +802,11 @@ msgstr "وصف"
 msgid "Delete"
 msgstr "حذف"
 
+#: src/views/certificate/components/RemoveCert.vue:92
+#, fuzzy
+msgid "Delete Certificate"
+msgstr "تجديد الشهادة"
+
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:35
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:547
 msgid "Delete Permanently"
@@ -977,7 +989,7 @@ msgstr "تم تعطيل الموقع %{site} على %{node} بنجاح"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:159
 #: src/views/site/site_edit/SiteEdit.vue:199
-#: src/views/site/site_list/columns.tsx:102 src/views/stream/StreamEdit.vue:182
+#: src/views/site/site_list/columns.tsx:111 src/views/stream/StreamEdit.vue:182
 #: src/views/stream/StreamList.vue:58 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "معطل"
@@ -1051,11 +1063,11 @@ msgstr[3] "ملف API"
 msgstr[4] "ملف API"
 msgstr[5] "ملف API"
 
-#: src/views/certificate/WildcardCertificate.vue:68
+#: src/views/certificate/components/WildcardCertificate.vue:68
 msgid "Domain"
 msgstr "نطاق"
 
-#: src/views/certificate/CertificateEditor.vue:112
+#: src/views/certificate/components/CertificateEditor.vue:112
 msgid "Domains list is empty, try to reopen Auto Cert for %{config}"
 msgstr "قائمة النطاقات فارغة، حاول إعادة فتح Auto Cert لـ %{config}"
 
@@ -1223,7 +1235,7 @@ msgstr "تفعيل TOTP"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:155
 #: src/views/site/site_edit/SiteEdit.vue:193
-#: src/views/site/site_list/columns.tsx:101
+#: src/views/site/site_list/columns.tsx:110
 #: src/views/stream/components/RightSettings.vue:81
 #: src/views/stream/StreamEdit.vue:176 src/views/stream/StreamList.vue:54
 #: src/views/user/userColumns.tsx:38
@@ -1434,6 +1446,11 @@ msgstr ""
 msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:66
+#, fuzzy
+msgid "Failed to delete certificate"
+msgstr "فشل في الحصول على الشهادة"
+
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:63
 #: src/views/stream/components/RightSettings.vue:45
 #: src/views/stream/StreamList.vue:100
@@ -1556,6 +1573,11 @@ msgstr "فشل في التفعيل %{msg}"
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:48
+#, fuzzy
+msgid "Failed to revoke certificate"
+msgstr "فشل في الحصول على الشهادة"
+
 #: src/views/site/site_edit/SiteEdit.vue:139
 #: src/views/stream/StreamEdit.vue:122
 msgid "Failed to save, syntax error(s) was detected in the configuration."
@@ -1738,6 +1760,15 @@ msgstr ""
 "إذا وصل عدد محاولات تسجيل الدخول الفاشلة من عنوان IP إلى الحد الأقصى "
 "للمحاولات في حد دقائق الحظر، سيتم حظر عنوان IP لفترة من الوقت."
 
+#: src/views/site/cert/components/AutoCertStepOne.vue:117
+#, fuzzy
+msgid ""
+"If you want to automatically revoke the old certificate, please enable this "
+"option."
+msgstr ""
+"إذا كان لنطاقك سجلات CNAME ولا يمكنك الحصول على شهادات، تحتاج إلى تفعيل هذا "
+"الخيار."
+
 #: src/views/preference/components/AddPasskey.vue:70
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr "إذا كان متصفحك يدعم WebAuthn Passkey، ستظهر نافذة حوار."
@@ -1750,12 +1781,12 @@ msgstr ""
 "إذا كان لنطاقك سجلات CNAME ولا يمكنك الحصول على شهادات، تحتاج إلى تفعيل هذا "
 "الخيار."
 
-#: src/views/certificate/CertificateList/Certificate.vue:20
+#: src/views/certificate/CertificateList/Certificate.vue:22
 msgid "Import"
 msgstr "استيراد"
 
 #: src/routes/modules/certificates.ts:46
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Import Certificate"
 msgstr "استيراد شهادة"
 
@@ -1886,11 +1917,11 @@ msgstr "رمز 2FA أو الاسترداد غير صالح"
 msgid "IP"
 msgstr "IP"
 
-#: src/views/certificate/CertificateList/Certificate.vue:28
+#: src/views/certificate/CertificateList/Certificate.vue:31
 msgid "Issue wildcard certificate"
 msgstr "إصدار شهادة wildcard"
 
-#: src/views/certificate/WildcardCertificate.vue:59
+#: src/views/certificate/components/WildcardCertificate.vue:59
 msgid "Issue Wildcard Certificate"
 msgstr "إصدار شهادة Wildcard"
 
@@ -1954,8 +1985,8 @@ msgstr "اتركه فارغًا إذا كنت لا تريد التعديل"
 msgid "Leave blank if you don't need this."
 msgstr "اتركه فارغًا إذا لم تكن بحاجة إلى ذلك."
 
-#: src/views/certificate/CertificateEditor.vue:220
-#: src/views/certificate/CertificateEditor.vue:233
+#: src/views/certificate/components/CertificateEditor.vue:222
+#: src/views/certificate/components/CertificateEditor.vue:235
 msgid "Leave blank will not change anything"
 msgstr "تركه فارغًا لن يغير شيئًا"
 
@@ -2005,7 +2036,7 @@ msgstr "مكان"
 msgid "Locations"
 msgstr "أماكن"
 
-#: src/views/certificate/CertificateEditor.vue:243
+#: src/views/certificate/components/CertificateEditor.vue:245
 msgid "Log"
 msgstr "سجل"
 
@@ -2047,7 +2078,7 @@ msgstr ""
 "الفاصل الزمني الذي تحدده بالدقائق."
 
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:163
-#: src/views/site/site_list/columns.tsx:103
+#: src/views/site/site_list/columns.tsx:112
 msgid "Maintenance"
 msgstr ""
 
@@ -2123,7 +2154,7 @@ msgid "Modify"
 msgstr "تعديل"
 
 #: src/routes/modules/certificates.ts:36
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Modify Certificate"
 msgstr "تعديل الشهادة"
 
@@ -2140,8 +2171,8 @@ msgid "Multi-line Directive"
 msgstr "توجيه متعدد الأسطر"
 
 #: src/views/certificate/ACMEUser.vue:13
-#: src/views/certificate/CertificateEditor.vue:160
 #: src/views/certificate/CertificateList/certColumns.tsx:10
+#: src/views/certificate/components/CertificateEditor.vue:162
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:305
@@ -2192,7 +2223,7 @@ msgstr "مسار جديد"
 msgid "New version released"
 msgstr "تم إصدار نسخة جديدة"
 
-#: src/views/certificate/WildcardCertificate.vue:91
+#: src/views/certificate/components/WildcardCertificate.vue:91
 #: src/views/site/cert/components/ObtainCert.vue:211
 #: src/views/site/site_add/SiteAdd.vue:141
 msgid "Next"
@@ -2359,7 +2390,7 @@ msgid "Node"
 msgstr "اسم العقدة"
 
 #: src/views/site/site_edit/RightSettings.vue:66
-#: src/views/site/site_list/columns.tsx:63
+#: src/views/site/site_list/columns.tsx:65
 #: src/views/stream/components/RightSettings.vue:90
 #: src/views/stream/StreamList.vue:30
 #, fuzzy
@@ -2713,6 +2744,10 @@ msgstr "يرجى اختيار عقدة واحدة على الأقل للترقي
 msgid "Please select at least one node to upgrade"
 msgstr "يرجى اختيار عقدة واحدة على الأقل للترقية"
 
+#: src/views/certificate/components/RemoveCert.vue:27
+msgid "Please type \"Revoke\" to confirm"
+msgstr ""
+
 #: src/views/preference/ServerSettings.vue:21
 #, fuzzy
 msgid "Port"
@@ -2985,8 +3020,8 @@ msgstr "إعادة التسمية بنجاح"
 msgid "Renamed successfully"
 msgstr "تمت إعادة التسمية بنجاح"
 
-#: src/views/certificate/RenewCert.vue:45
-#: src/views/certificate/RenewCert.vue:49
+#: src/views/certificate/components/RenewCert.vue:45
+#: src/views/certificate/components/RenewCert.vue:49
 msgid "Renew Certificate"
 msgstr "تجديد الشهادة"
 
@@ -2998,8 +3033,8 @@ msgstr "خطأ في تجديد الشهادة"
 msgid "Renew Certificate Success"
 msgstr "تجديد الشهادة بنجاح"
 
-#: src/views/certificate/RenewCert.vue:27
-#: src/views/certificate/WildcardCertificate.vue:48
+#: src/views/certificate/components/RenewCert.vue:27
+#: src/views/certificate/components/WildcardCertificate.vue:48
 msgid "Renew successfully"
 msgstr "تم التجديد بنجاح"
 
@@ -3085,6 +3120,27 @@ msgstr "مجلد تكوينات Nginx"
 msgid "Restore this version"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:26
+#: src/views/certificate/components/RemoveCert.vue:95
+msgid "Revoke"
+msgstr ""
+
+#: src/views/site/cert/components/AutoCertStepOne.vue:114
+#, fuzzy
+msgid "Revoke Old Certificate"
+msgstr "تجديد الشهادة"
+
+#: src/views/certificate/components/RemoveCert.vue:109
+#, fuzzy
+msgid "Revoke this certificate"
+msgstr "تجديد الشهادة"
+
+#: src/views/certificate/components/RemoveCert.vue:117
+msgid ""
+"Revoking a certificate will affect any services currently using it. This "
+"action cannot be undone."
+msgstr ""
+
 #: src/views/preference/AuthSettings.vue:107
 msgid "RP Display Name"
 msgstr "اسم العرض RP"
@@ -3108,7 +3164,7 @@ msgstr "يعمل"
 #: src/components/ChatGPT/ChatGPT.vue:355
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:64
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
-#: src/views/certificate/CertificateEditor.vue:262
+#: src/views/certificate/components/CertificateEditor.vue:264
 #: src/views/config/components/ConfigName.vue:59
 #: src/views/config/ConfigEditor.vue:271
 #: src/views/preference/components/Passkey.vue:130
@@ -3172,7 +3228,7 @@ msgstr "تم حفظ الموقع %{site} إلى %{node} بنجاح"
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
-#: src/views/certificate/CertificateEditor.vue:49
+#: src/views/certificate/components/CertificateEditor.vue:49
 #: src/views/preference/Preference.vue:124
 msgid "Save successfully"
 msgstr "تم الحفظ بنجاح"
@@ -3343,7 +3399,7 @@ msgstr "مجلد"
 msgid "Skip Installation"
 msgstr "تثبيت"
 
-#: src/views/certificate/CertificateEditor.vue:211
+#: src/views/certificate/components/CertificateEditor.vue:213
 msgid "SSL Certificate Content"
 msgstr "محتوى شهادة SSL"
 
@@ -3356,15 +3412,15 @@ msgstr ""
 msgid "SSL certificate file not found"
 msgstr "محتوى مفتاح شهادة SSL"
 
-#: src/views/certificate/CertificateEditor.vue:224
+#: src/views/certificate/components/CertificateEditor.vue:226
 msgid "SSL Certificate Key Content"
 msgstr "محتوى مفتاح شهادة SSL"
 
-#: src/views/certificate/CertificateEditor.vue:190
+#: src/views/certificate/components/CertificateEditor.vue:192
 msgid "SSL Certificate Key Path"
 msgstr "مسار مفتاح شهادة SSL"
 
-#: src/views/certificate/CertificateEditor.vue:175
+#: src/views/certificate/components/CertificateEditor.vue:177
 #: src/views/preference/ServerSettings.vue:36
 msgid "SSL Certificate Path"
 msgstr "مسار شهادة SSL"
@@ -3410,7 +3466,7 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/site/site_list/columns.tsx:80 src/views/stream/StreamList.vue:47
+#: src/views/site/site_list/columns.tsx:89 src/views/stream/StreamList.vue:47
 msgid "Status"
 msgstr "الحالة"
 
@@ -3533,7 +3589,7 @@ msgstr "مزامنة العقد"
 msgid "Sync strategy"
 msgstr "استراتيجية المزامنة"
 
-#: src/views/certificate/CertificateEditor.vue:204
+#: src/views/certificate/components/CertificateEditor.vue:206
 msgid "Sync to"
 msgstr "مزامنة إلى"
 
@@ -3551,7 +3607,7 @@ msgstr "نظام"
 msgid "System Backup"
 msgstr "نظام"
 
-#: src/views/certificate/ACMEUserSelector.vue:88
+#: src/views/certificate/components/ACMEUserSelector.vue:88
 msgid "System Initial User"
 msgstr "مستخدم النظام الأولي"
 
@@ -3605,11 +3661,11 @@ msgstr ""
 "يجب أن يحتوي اسم العقدة على حروف وأحرف يونيكود وأرقام وشرطات وعلامات وصل "
 "ونقاط فقط."
 
-#: src/views/certificate/CertificateEditor.vue:214
+#: src/views/certificate/components/CertificateEditor.vue:216
 msgid "The input is not a SSL Certificate"
 msgstr "الإدخال ليس شهادة SSL"
 
-#: src/views/certificate/CertificateEditor.vue:227
+#: src/views/certificate/components/CertificateEditor.vue:229
 msgid "The input is not a SSL Certificate Key"
 msgstr "المدخل ليس مفتاح شهادة SSL"
 
@@ -3639,11 +3695,11 @@ msgstr ""
 msgid "The parameter of server_name is required"
 msgstr "عامل server_name مطلوب"
 
-#: src/views/certificate/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:181
 msgid "The path exists, but the file is not a certificate"
 msgstr "المسار موجود، لكن الملف ليس شهادة"
 
-#: src/views/certificate/CertificateEditor.vue:194
+#: src/views/certificate/components/CertificateEditor.vue:196
 msgid "The path exists, but the file is not a private key"
 msgstr "المسار موجود، لكن الملف ليس مفتاحًا خاصًا"
 
@@ -3694,17 +3750,17 @@ msgid ""
 "lose access to your account."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:102
+#: src/views/certificate/components/CertificateEditor.vue:102
 msgid "This Auto Cert item is invalid, please remove it."
 msgstr "هذا العنصر في الشهادة التلقائية غير صالح، يرجى إزالته."
 
-#: src/views/certificate/CertificateEditor.vue:92
+#: src/views/certificate/components/CertificateEditor.vue:92
 msgid "This certificate is managed by Nginx UI"
 msgstr "يتم إدارة هذه الشهادة بواسطة Nginx UI"
 
-#: src/views/certificate/CertificateEditor.vue:163
-#: src/views/certificate/CertificateEditor.vue:177
-#: src/views/certificate/CertificateEditor.vue:192
+#: src/views/certificate/components/CertificateEditor.vue:165
+#: src/views/certificate/components/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:194
 msgid "This field is required"
 msgstr "هذا الحقل مطلوب"
 
@@ -3726,6 +3782,12 @@ msgid ""
 "This field should only contain letters, unicode characters, numbers, and -_."
 msgstr "يجب أن يحتوي هذا الحقل على حروف وأحرف يونيكود وأرقام و-_. فقط."
 
+#: src/views/certificate/components/RemoveCert.vue:103
+msgid ""
+"This operation will only remove the certificate from the database. The "
+"certificate files on the file system will not be deleted."
+msgstr ""
+
 #: src/views/system/Backup/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -3769,6 +3831,10 @@ msgstr "نصائح"
 msgid "Title"
 msgstr "عنوان"
 
+#: src/views/certificate/components/RemoveCert.vue:121
+msgid "To confirm revocation, please type \"Revoke\" in the field below:"
+msgstr ""
+
 #: src/views/preference/components/TOTP.vue:68
 msgid ""
 "To enable it, you need to install the Google or Microsoft Authenticator app "
@@ -3863,7 +3929,7 @@ msgstr "تم التحديث بنجاح"
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:75
-#: src/views/site/site_list/columns.tsx:110
+#: src/views/site/site_list/columns.tsx:82
 #: src/views/stream/components/RightSettings.vue:99
 #: src/views/stream/StreamList.vue:67 src/views/user/userColumns.tsx:54
 msgid "Updated at"
@@ -4015,6 +4081,10 @@ msgstr "ويب أوثن"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:54
+msgid "WebSocket connection error"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:83
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "

+ 114 - 44
app/src/language/de_DE/app.po

@@ -31,7 +31,7 @@ msgid "Access Logs"
 msgstr "Zugriffslog"
 
 #: src/routes/modules/certificates.ts:20 src/views/certificate/ACMEUser.vue:113
-#: src/views/certificate/ACMEUserSelector.vue:85
+#: src/views/certificate/components/ACMEUserSelector.vue:85
 #, fuzzy
 msgid "ACME User"
 msgstr "Benutzername"
@@ -46,7 +46,7 @@ msgstr "Benutzername"
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
 #: src/views/preference/components/ExternalNotify/columns.ts:46
-#: src/views/site/site_list/columns.tsx:117 src/views/stream/StreamList.vue:74
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/StreamList.vue:74
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Aktion"
@@ -295,7 +295,7 @@ msgstr ""
 msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:255
+#: src/views/certificate/components/CertificateEditor.vue:257
 #: src/views/config/ConfigEditor.vue:262 src/views/config/ConfigList.vue:112
 #: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:285
@@ -483,6 +483,12 @@ msgstr "Certificate has expired"
 msgid "Certificate path is empty"
 msgstr "Konfigurationen"
 
+#: src/views/certificate/components/RemoveCert.vue:41
+#: src/views/certificate/components/RemoveCert.vue:61
+#, fuzzy
+msgid "Certificate removed successfully"
+msgstr "Erfolgreich deaktiviert"
+
 #: src/views/preference/CertSettings.vue:27
 #, fuzzy
 msgid "Certificate Renewal Interval"
@@ -493,7 +499,7 @@ msgstr "Zeitifikat ist gültig"
 msgid "Certificate renewed successfully"
 msgstr "Erfolgreich deaktiviert"
 
-#: src/views/certificate/CertificateEditor.vue:128
+#: src/views/certificate/components/CertificateEditor.vue:128
 #: src/views/site/cert/Cert.vue:60
 #, fuzzy
 msgid "Certificate Status"
@@ -502,7 +508,7 @@ msgstr[0] "Zertifikatsstatus"
 msgstr[1] "Zertifikatsstatus"
 
 #: src/routes/modules/certificates.ts:11
-#: src/views/certificate/CertificateList/Certificate.vue:13
+#: src/views/certificate/CertificateList/Certificate.vue:14
 #, fuzzy
 msgid "Certificates"
 msgstr "Zertifikatsstatus"
@@ -813,6 +819,7 @@ msgstr "Beschreibung"
 
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:21
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
+#: src/views/certificate/components/RemoveCert.vue:87
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
 #: src/views/site/site_list/SiteList.vue:176
@@ -820,6 +827,11 @@ msgstr "Beschreibung"
 msgid "Delete"
 msgstr "Löschen"
 
+#: src/views/certificate/components/RemoveCert.vue:92
+#, fuzzy
+msgid "Delete Certificate"
+msgstr "Zertifikat ist gültig"
+
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:35
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:547
 msgid "Delete Permanently"
@@ -1008,7 +1020,7 @@ msgstr "Speichern erfolgreich"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:159
 #: src/views/site/site_edit/SiteEdit.vue:199
-#: src/views/site/site_list/columns.tsx:102 src/views/stream/StreamEdit.vue:182
+#: src/views/site/site_list/columns.tsx:111 src/views/stream/StreamEdit.vue:182
 #: src/views/stream/StreamList.vue:58 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Deaktiviert"
@@ -1085,11 +1097,11 @@ msgid_plural "Documents"
 msgstr[0] "API-Dokument"
 msgstr[1] "API-Dokument"
 
-#: src/views/certificate/WildcardCertificate.vue:68
+#: src/views/certificate/components/WildcardCertificate.vue:68
 msgid "Domain"
 msgstr "Domain"
 
-#: src/views/certificate/CertificateEditor.vue:112
+#: src/views/certificate/components/CertificateEditor.vue:112
 msgid "Domains list is empty, try to reopen Auto Cert for %{config}"
 msgstr ""
 "Domänenliste ist leer, versuche Auto-Zertifikat für %{config} erneut zu "
@@ -1268,7 +1280,7 @@ msgstr "Aktiviere TLS"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:155
 #: src/views/site/site_edit/SiteEdit.vue:193
-#: src/views/site/site_list/columns.tsx:101
+#: src/views/site/site_list/columns.tsx:110
 #: src/views/stream/components/RightSettings.vue:81
 #: src/views/stream/StreamEdit.vue:176 src/views/stream/StreamList.vue:54
 #: src/views/user/userColumns.tsx:38
@@ -1481,6 +1493,11 @@ msgstr ""
 msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:66
+#, fuzzy
+msgid "Failed to delete certificate"
+msgstr "Zertifikat ist gültig"
+
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:63
 #: src/views/stream/components/RightSettings.vue:45
 #: src/views/stream/StreamList.vue:100
@@ -1599,6 +1616,11 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:48
+#, fuzzy
+msgid "Failed to revoke certificate"
+msgstr "Zertifikat ist gültig"
+
 #: src/views/site/site_edit/SiteEdit.vue:139
 #: src/views/stream/StreamEdit.vue:122
 msgid "Failed to save, syntax error(s) was detected in the configuration."
@@ -1786,6 +1808,15 @@ msgstr ""
 "maximalen Versuche in der Sperrschwellenzeit erreicht, wird die IP für eine "
 "bestimmte Zeit gesperrt."
 
+#: src/views/site/cert/components/AutoCertStepOne.vue:117
+#, fuzzy
+msgid ""
+"If you want to automatically revoke the old certificate, please enable this "
+"option."
+msgstr ""
+"Wenn deine Domain CNAME-Einträge hat und du keine Zertifikate erhalten "
+"kannst, musst du diese Option aktivieren."
+
 #: src/views/preference/components/AddPasskey.vue:70
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr ""
@@ -1800,12 +1831,12 @@ msgstr ""
 "Wenn deine Domain CNAME-Einträge hat und du keine Zertifikate erhalten "
 "kannst, musst du diese Option aktivieren."
 
-#: src/views/certificate/CertificateList/Certificate.vue:20
+#: src/views/certificate/CertificateList/Certificate.vue:22
 msgid "Import"
 msgstr "Import"
 
 #: src/routes/modules/certificates.ts:46
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 #, fuzzy
 msgid "Import Certificate"
 msgstr "Zertifikatsstatus"
@@ -1937,12 +1968,12 @@ msgstr "Ungültiger 2FA- oder Wiederherstellungscode"
 msgid "IP"
 msgstr ""
 
-#: src/views/certificate/CertificateList/Certificate.vue:28
+#: src/views/certificate/CertificateList/Certificate.vue:31
 #, fuzzy
 msgid "Issue wildcard certificate"
 msgstr "Zertifikat ist gültig"
 
-#: src/views/certificate/WildcardCertificate.vue:59
+#: src/views/certificate/components/WildcardCertificate.vue:59
 #, fuzzy
 msgid "Issue Wildcard Certificate"
 msgstr "Zertifikatsstatus"
@@ -2011,8 +2042,8 @@ msgstr "Leer lassen für keine Änderung"
 msgid "Leave blank if you don't need this."
 msgstr "Leeer lassen, wenn du dies nicht benötigst."
 
-#: src/views/certificate/CertificateEditor.vue:220
-#: src/views/certificate/CertificateEditor.vue:233
+#: src/views/certificate/components/CertificateEditor.vue:222
+#: src/views/certificate/components/CertificateEditor.vue:235
 #, fuzzy
 msgid "Leave blank will not change anything"
 msgstr "Leeer lassen, wenn du dies nicht benötigst."
@@ -2067,7 +2098,7 @@ msgstr "Ort"
 msgid "Locations"
 msgstr "Orte"
 
-#: src/views/certificate/CertificateEditor.vue:243
+#: src/views/certificate/components/CertificateEditor.vue:245
 #, fuzzy
 msgid "Log"
 msgstr "Login"
@@ -2110,7 +2141,7 @@ msgstr ""
 "von dir in Minuten festgelegten Intervall aus."
 
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:163
-#: src/views/site/site_list/columns.tsx:103
+#: src/views/site/site_list/columns.tsx:112
 msgid "Maintenance"
 msgstr ""
 
@@ -2192,7 +2223,7 @@ msgid "Modify"
 msgstr "Konfiguration bearbeiten"
 
 #: src/routes/modules/certificates.ts:36
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 #, fuzzy
 msgid "Modify Certificate"
 msgstr "Zertifikatsstatus"
@@ -2212,8 +2243,8 @@ msgid "Multi-line Directive"
 msgstr "Einzelne Anweisung"
 
 #: src/views/certificate/ACMEUser.vue:13
-#: src/views/certificate/CertificateEditor.vue:160
 #: src/views/certificate/CertificateList/certColumns.tsx:10
+#: src/views/certificate/components/CertificateEditor.vue:162
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:305
@@ -2266,7 +2297,7 @@ msgstr "Pfad"
 msgid "New version released"
 msgstr "Neue Version veröffentlicht"
 
-#: src/views/certificate/WildcardCertificate.vue:91
+#: src/views/certificate/components/WildcardCertificate.vue:91
 #: src/views/site/cert/components/ObtainCert.vue:211
 #: src/views/site/site_add/SiteAdd.vue:141
 msgid "Next"
@@ -2437,7 +2468,7 @@ msgid "Node"
 msgstr "Benuztername"
 
 #: src/views/site/site_edit/RightSettings.vue:66
-#: src/views/site/site_list/columns.tsx:63
+#: src/views/site/site_list/columns.tsx:65
 #: src/views/stream/components/RightSettings.vue:90
 #: src/views/stream/StreamList.vue:30
 #, fuzzy
@@ -2810,6 +2841,10 @@ msgstr "Bitte wähle mindestens einen Knoten zum Upgrade aus"
 msgid "Please select at least one node to upgrade"
 msgstr "Bitte wähle mindestens einen Knoten zum Upgrade aus"
 
+#: src/views/certificate/components/RemoveCert.vue:27
+msgid "Please type \"Revoke\" to confirm"
+msgstr ""
+
 #: src/views/preference/ServerSettings.vue:21
 msgid "Port"
 msgstr ""
@@ -3099,8 +3134,8 @@ msgstr "Aktivierung erfolgreich"
 msgid "Renamed successfully"
 msgstr "Aktivierung erfolgreich"
 
-#: src/views/certificate/RenewCert.vue:45
-#: src/views/certificate/RenewCert.vue:49
+#: src/views/certificate/components/RenewCert.vue:45
+#: src/views/certificate/components/RenewCert.vue:49
 #, fuzzy
 msgid "Renew Certificate"
 msgstr "Zertifikat ist gültig"
@@ -3115,8 +3150,8 @@ msgstr "Zertifikat ist gültig"
 msgid "Renew Certificate Success"
 msgstr "Zertifikat ist gültig"
 
-#: src/views/certificate/RenewCert.vue:27
-#: src/views/certificate/WildcardCertificate.vue:48
+#: src/views/certificate/components/RenewCert.vue:27
+#: src/views/certificate/components/WildcardCertificate.vue:48
 #, fuzzy
 msgid "Renew successfully"
 msgstr "Aktivierung erfolgreich"
@@ -3203,6 +3238,27 @@ msgstr "Name der Konfiguration"
 msgid "Restore this version"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:26
+#: src/views/certificate/components/RemoveCert.vue:95
+msgid "Revoke"
+msgstr ""
+
+#: src/views/site/cert/components/AutoCertStepOne.vue:114
+#, fuzzy
+msgid "Revoke Old Certificate"
+msgstr "Zertifikat ist gültig"
+
+#: src/views/certificate/components/RemoveCert.vue:109
+#, fuzzy
+msgid "Revoke this certificate"
+msgstr "Zertifikat ist gültig"
+
+#: src/views/certificate/components/RemoveCert.vue:117
+msgid ""
+"Revoking a certificate will affect any services currently using it. This "
+"action cannot be undone."
+msgstr ""
+
 #: src/views/preference/AuthSettings.vue:107
 msgid "RP Display Name"
 msgstr "RP-Anzeigename"
@@ -3227,7 +3283,7 @@ msgstr "Arbeite"
 #: src/components/ChatGPT/ChatGPT.vue:355
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:64
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
-#: src/views/certificate/CertificateEditor.vue:262
+#: src/views/certificate/components/CertificateEditor.vue:264
 #: src/views/config/components/ConfigName.vue:59
 #: src/views/config/ConfigEditor.vue:271
 #: src/views/preference/components/Passkey.vue:130
@@ -3293,7 +3349,7 @@ msgstr "Speichern erfolgreich"
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
-#: src/views/certificate/CertificateEditor.vue:49
+#: src/views/certificate/components/CertificateEditor.vue:49
 #: src/views/preference/Preference.vue:124
 #, fuzzy
 msgid "Save successfully"
@@ -3465,7 +3521,7 @@ msgstr ""
 msgid "Skip Installation"
 msgstr "Installieren"
 
-#: src/views/certificate/CertificateEditor.vue:211
+#: src/views/certificate/components/CertificateEditor.vue:213
 #, fuzzy
 msgid "SSL Certificate Content"
 msgstr "Zertifikatsstatus"
@@ -3479,17 +3535,17 @@ msgstr ""
 msgid "SSL certificate file not found"
 msgstr "Zertifikatsstatus"
 
-#: src/views/certificate/CertificateEditor.vue:224
+#: src/views/certificate/components/CertificateEditor.vue:226
 #, fuzzy
 msgid "SSL Certificate Key Content"
 msgstr "Zertifikatsstatus"
 
-#: src/views/certificate/CertificateEditor.vue:190
+#: src/views/certificate/components/CertificateEditor.vue:192
 #, fuzzy
 msgid "SSL Certificate Key Path"
 msgstr "Zertifikatsstatus"
 
-#: src/views/certificate/CertificateEditor.vue:175
+#: src/views/certificate/components/CertificateEditor.vue:177
 #: src/views/preference/ServerSettings.vue:36
 #, fuzzy
 msgid "SSL Certificate Path"
@@ -3538,7 +3594,7 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/site/site_list/columns.tsx:80 src/views/stream/StreamList.vue:47
+#: src/views/site/site_list/columns.tsx:89 src/views/stream/StreamList.vue:47
 msgid "Status"
 msgstr "Status"
 
@@ -3666,7 +3722,7 @@ msgstr "Synchrone Knoten"
 msgid "Sync strategy"
 msgstr "Zertifikat ist gültig"
 
-#: src/views/certificate/CertificateEditor.vue:204
+#: src/views/certificate/components/CertificateEditor.vue:206
 msgid "Sync to"
 msgstr "Synchronisieren mit"
 
@@ -3684,7 +3740,7 @@ msgstr "System"
 msgid "System Backup"
 msgstr "System"
 
-#: src/views/certificate/ACMEUserSelector.vue:88
+#: src/views/certificate/components/ACMEUserSelector.vue:88
 msgid "System Initial User"
 msgstr "System-Startbenutzer"
 
@@ -3738,11 +3794,11 @@ msgstr ""
 "Die ICP-Nummer sollte nur Buchstaben, Unicode, Zahlen, Bindestriche, "
 "Doppelpunkte und Punkte enthalten."
 
-#: src/views/certificate/CertificateEditor.vue:214
+#: src/views/certificate/components/CertificateEditor.vue:216
 msgid "The input is not a SSL Certificate"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:227
+#: src/views/certificate/components/CertificateEditor.vue:229
 #, fuzzy
 msgid "The input is not a SSL Certificate Key"
 msgstr "Zertifikatsstatus"
@@ -3773,12 +3829,12 @@ msgstr ""
 msgid "The parameter of server_name is required"
 msgstr "server_name-Parameter ist erforderlich"
 
-#: src/views/certificate/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:181
 #, fuzzy
 msgid "The path exists, but the file is not a certificate"
 msgstr "Zertifikatsstatus"
 
-#: src/views/certificate/CertificateEditor.vue:194
+#: src/views/certificate/components/CertificateEditor.vue:196
 msgid "The path exists, but the file is not a private key"
 msgstr "Der Pfad existiert, aber die Datei ist kein privater Schlüssel"
 
@@ -3830,17 +3886,17 @@ msgid ""
 "lose access to your account."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:102
+#: src/views/certificate/components/CertificateEditor.vue:102
 msgid "This Auto Cert item is invalid, please remove it."
 msgstr "Dieses Auto-Zertifikatselement ist ungültig, bitte entferne es."
 
-#: src/views/certificate/CertificateEditor.vue:92
+#: src/views/certificate/components/CertificateEditor.vue:92
 msgid "This certificate is managed by Nginx UI"
 msgstr "Dieses Zertifikat wird von Nginx UI verwaltet"
 
-#: src/views/certificate/CertificateEditor.vue:163
-#: src/views/certificate/CertificateEditor.vue:177
-#: src/views/certificate/CertificateEditor.vue:192
+#: src/views/certificate/components/CertificateEditor.vue:165
+#: src/views/certificate/components/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:194
 msgid "This field is required"
 msgstr "Dieses Feld ist erforderlich"
 
@@ -3863,6 +3919,12 @@ msgid ""
 msgstr ""
 "Dieses Feld sollte nur Buchstaben, Unicode-Zeichen, Zahlen und -_ enthalten."
 
+#: src/views/certificate/components/RemoveCert.vue:103
+msgid ""
+"This operation will only remove the certificate from the database. The "
+"certificate files on the file system will not be deleted."
+msgstr ""
+
 #: src/views/system/Backup/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -3908,6 +3970,10 @@ msgstr "Tipps"
 msgid "Title"
 msgstr "Titel"
 
+#: src/views/certificate/components/RemoveCert.vue:121
+msgid "To confirm revocation, please type \"Revoke\" in the field below:"
+msgstr ""
+
 #: src/views/preference/components/TOTP.vue:68
 msgid ""
 "To enable it, you need to install the Google or Microsoft Authenticator app "
@@ -3999,7 +4065,7 @@ msgstr "Speichern erfolgreich"
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:75
-#: src/views/site/site_list/columns.tsx:110
+#: src/views/site/site_list/columns.tsx:82
 #: src/views/stream/components/RightSettings.vue:99
 #: src/views/stream/StreamList.vue:67 src/views/user/userColumns.tsx:54
 msgid "Updated at"
@@ -4159,6 +4225,10 @@ msgstr "Webauthn"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:54
+msgid "WebSocket connection error"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:83
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "

+ 111 - 44
app/src/language/en/app.po

@@ -32,7 +32,7 @@ msgid "Access Logs"
 msgstr "Sites List"
 
 #: src/routes/modules/certificates.ts:20 src/views/certificate/ACMEUser.vue:113
-#: src/views/certificate/ACMEUserSelector.vue:85
+#: src/views/certificate/components/ACMEUserSelector.vue:85
 #, fuzzy
 msgid "ACME User"
 msgstr "Username"
@@ -47,7 +47,7 @@ msgstr "Username"
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
 #: src/views/preference/components/ExternalNotify/columns.ts:46
-#: src/views/site/site_list/columns.tsx:117 src/views/stream/StreamList.vue:74
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/StreamList.vue:74
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Action"
@@ -292,7 +292,7 @@ msgstr ""
 msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:255
+#: src/views/certificate/components/CertificateEditor.vue:257
 #: src/views/config/ConfigEditor.vue:262 src/views/config/ConfigList.vue:112
 #: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:285
@@ -477,6 +477,12 @@ msgstr "Certificate has expired"
 msgid "Certificate path is empty"
 msgstr "Configurations"
 
+#: src/views/certificate/components/RemoveCert.vue:41
+#: src/views/certificate/components/RemoveCert.vue:61
+#, fuzzy
+msgid "Certificate removed successfully"
+msgstr "Disabled successfully"
+
 #: src/views/preference/CertSettings.vue:27
 #, fuzzy
 msgid "Certificate Renewal Interval"
@@ -487,7 +493,7 @@ msgstr "Certificate is valid"
 msgid "Certificate renewed successfully"
 msgstr "Disabled successfully"
 
-#: src/views/certificate/CertificateEditor.vue:128
+#: src/views/certificate/components/CertificateEditor.vue:128
 #: src/views/site/cert/Cert.vue:60
 #, fuzzy
 msgid "Certificate Status"
@@ -496,7 +502,7 @@ msgstr[0] "Certificate Status"
 msgstr[1] "Certificate Status"
 
 #: src/routes/modules/certificates.ts:11
-#: src/views/certificate/CertificateList/Certificate.vue:13
+#: src/views/certificate/CertificateList/Certificate.vue:14
 #, fuzzy
 msgid "Certificates"
 msgstr "Certificate Status"
@@ -804,6 +810,7 @@ msgstr "Enable failed"
 
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:21
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
+#: src/views/certificate/components/RemoveCert.vue:87
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
 #: src/views/site/site_list/SiteList.vue:176
@@ -811,6 +818,11 @@ msgstr "Enable failed"
 msgid "Delete"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:92
+#, fuzzy
+msgid "Delete Certificate"
+msgstr "Certificate is valid"
+
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:35
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:547
 msgid "Delete Permanently"
@@ -999,7 +1011,7 @@ msgstr "Saved successfully"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:159
 #: src/views/site/site_edit/SiteEdit.vue:199
-#: src/views/site/site_list/columns.tsx:102 src/views/stream/StreamEdit.vue:182
+#: src/views/site/site_list/columns.tsx:111 src/views/stream/StreamEdit.vue:182
 #: src/views/stream/StreamList.vue:58 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Disabled"
@@ -1075,11 +1087,11 @@ msgid_plural "Documents"
 msgstr[0] "Comments"
 msgstr[1] "Comments"
 
-#: src/views/certificate/WildcardCertificate.vue:68
+#: src/views/certificate/components/WildcardCertificate.vue:68
 msgid "Domain"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:112
+#: src/views/certificate/components/CertificateEditor.vue:112
 msgid "Domains list is empty, try to reopen Auto Cert for %{config}"
 msgstr ""
 
@@ -1254,7 +1266,7 @@ msgstr "Enable TLS"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:155
 #: src/views/site/site_edit/SiteEdit.vue:193
-#: src/views/site/site_list/columns.tsx:101
+#: src/views/site/site_list/columns.tsx:110
 #: src/views/stream/components/RightSettings.vue:81
 #: src/views/stream/StreamEdit.vue:176 src/views/stream/StreamList.vue:54
 #: src/views/user/userColumns.tsx:38
@@ -1467,6 +1479,11 @@ msgstr ""
 msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:66
+#, fuzzy
+msgid "Failed to delete certificate"
+msgstr "Certificate is valid"
+
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:63
 #: src/views/stream/components/RightSettings.vue:45
 #: src/views/stream/StreamList.vue:100
@@ -1590,6 +1607,11 @@ msgstr "Failed to enable %{msg}"
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:48
+#, fuzzy
+msgid "Failed to revoke certificate"
+msgstr "Certificate is valid"
+
 #: src/views/site/site_edit/SiteEdit.vue:139
 #: src/views/stream/StreamEdit.vue:122
 msgid "Failed to save, syntax error(s) was detected in the configuration."
@@ -1771,6 +1793,12 @@ msgid ""
 "ban threshold minutes, the ip will be banned for a period of time."
 msgstr ""
 
+#: src/views/site/cert/components/AutoCertStepOne.vue:117
+msgid ""
+"If you want to automatically revoke the old certificate, please enable this "
+"option."
+msgstr ""
+
 #: src/views/preference/components/AddPasskey.vue:70
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr ""
@@ -1781,12 +1809,12 @@ msgid ""
 "need to enable this option."
 msgstr ""
 
-#: src/views/certificate/CertificateList/Certificate.vue:20
+#: src/views/certificate/CertificateList/Certificate.vue:22
 msgid "Import"
 msgstr ""
 
 #: src/routes/modules/certificates.ts:46
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 #, fuzzy
 msgid "Import Certificate"
 msgstr "Certificate Status"
@@ -1922,12 +1950,12 @@ msgstr "Invalid E-mail!"
 msgid "IP"
 msgstr ""
 
-#: src/views/certificate/CertificateList/Certificate.vue:28
+#: src/views/certificate/CertificateList/Certificate.vue:31
 #, fuzzy
 msgid "Issue wildcard certificate"
 msgstr "Certificate is valid"
 
-#: src/views/certificate/WildcardCertificate.vue:59
+#: src/views/certificate/components/WildcardCertificate.vue:59
 #, fuzzy
 msgid "Issue Wildcard Certificate"
 msgstr "Certificate Status"
@@ -1996,8 +2024,8 @@ msgstr "Leave blank for no change"
 msgid "Leave blank if you don't need this."
 msgstr "Leave blank for no change"
 
-#: src/views/certificate/CertificateEditor.vue:220
-#: src/views/certificate/CertificateEditor.vue:233
+#: src/views/certificate/components/CertificateEditor.vue:222
+#: src/views/certificate/components/CertificateEditor.vue:235
 #, fuzzy
 msgid "Leave blank will not change anything"
 msgstr "Leave blank for no change"
@@ -2052,7 +2080,7 @@ msgstr "Location"
 msgid "Locations"
 msgstr "Locations"
 
-#: src/views/certificate/CertificateEditor.vue:243
+#: src/views/certificate/components/CertificateEditor.vue:245
 #, fuzzy
 msgid "Log"
 msgstr "Login"
@@ -2088,7 +2116,7 @@ msgid ""
 msgstr ""
 
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:163
-#: src/views/site/site_list/columns.tsx:103
+#: src/views/site/site_list/columns.tsx:112
 msgid "Maintenance"
 msgstr ""
 
@@ -2169,7 +2197,7 @@ msgid "Modify"
 msgstr "Modify Config"
 
 #: src/routes/modules/certificates.ts:36
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 #, fuzzy
 msgid "Modify Certificate"
 msgstr "Certificate Status"
@@ -2189,8 +2217,8 @@ msgid "Multi-line Directive"
 msgstr "Single Directive"
 
 #: src/views/certificate/ACMEUser.vue:13
-#: src/views/certificate/CertificateEditor.vue:160
 #: src/views/certificate/CertificateList/certColumns.tsx:10
+#: src/views/certificate/components/CertificateEditor.vue:162
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:305
@@ -2243,7 +2271,7 @@ msgstr "Path"
 msgid "New version released"
 msgstr ""
 
-#: src/views/certificate/WildcardCertificate.vue:91
+#: src/views/certificate/components/WildcardCertificate.vue:91
 #: src/views/site/cert/components/ObtainCert.vue:211
 #: src/views/site/site_add/SiteAdd.vue:141
 msgid "Next"
@@ -2413,7 +2441,7 @@ msgid "Node"
 msgstr "Username"
 
 #: src/views/site/site_edit/RightSettings.vue:66
-#: src/views/site/site_list/columns.tsx:63
+#: src/views/site/site_list/columns.tsx:65
 #: src/views/stream/components/RightSettings.vue:90
 #: src/views/stream/StreamList.vue:30
 #, fuzzy
@@ -2763,6 +2791,10 @@ msgstr ""
 msgid "Please select at least one node to upgrade"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:27
+msgid "Please type \"Revoke\" to confirm"
+msgstr ""
+
 #: src/views/preference/ServerSettings.vue:21
 msgid "Port"
 msgstr ""
@@ -3051,8 +3083,8 @@ msgstr "Enabled successfully"
 msgid "Renamed successfully"
 msgstr "Enabled successfully"
 
-#: src/views/certificate/RenewCert.vue:45
-#: src/views/certificate/RenewCert.vue:49
+#: src/views/certificate/components/RenewCert.vue:45
+#: src/views/certificate/components/RenewCert.vue:49
 #, fuzzy
 msgid "Renew Certificate"
 msgstr "Certificate is valid"
@@ -3067,8 +3099,8 @@ msgstr "Certificate is valid"
 msgid "Renew Certificate Success"
 msgstr "Certificate is valid"
 
-#: src/views/certificate/RenewCert.vue:27
-#: src/views/certificate/WildcardCertificate.vue:48
+#: src/views/certificate/components/RenewCert.vue:27
+#: src/views/certificate/components/WildcardCertificate.vue:48
 #, fuzzy
 msgid "Renew successfully"
 msgstr "Enabled successfully"
@@ -3154,6 +3186,27 @@ msgstr "Configuration Name"
 msgid "Restore this version"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:26
+#: src/views/certificate/components/RemoveCert.vue:95
+msgid "Revoke"
+msgstr ""
+
+#: src/views/site/cert/components/AutoCertStepOne.vue:114
+#, fuzzy
+msgid "Revoke Old Certificate"
+msgstr "Certificate is valid"
+
+#: src/views/certificate/components/RemoveCert.vue:109
+#, fuzzy
+msgid "Revoke this certificate"
+msgstr "Certificate is valid"
+
+#: src/views/certificate/components/RemoveCert.vue:117
+msgid ""
+"Revoking a certificate will affect any services currently using it. This "
+"action cannot be undone."
+msgstr ""
+
 #: src/views/preference/AuthSettings.vue:107
 msgid "RP Display Name"
 msgstr ""
@@ -3178,7 +3231,7 @@ msgstr ""
 #: src/components/ChatGPT/ChatGPT.vue:355
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:64
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
-#: src/views/certificate/CertificateEditor.vue:262
+#: src/views/certificate/components/CertificateEditor.vue:264
 #: src/views/config/components/ConfigName.vue:59
 #: src/views/config/ConfigEditor.vue:271
 #: src/views/preference/components/Passkey.vue:130
@@ -3244,7 +3297,7 @@ msgstr "Saved successfully"
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
-#: src/views/certificate/CertificateEditor.vue:49
+#: src/views/certificate/components/CertificateEditor.vue:49
 #: src/views/preference/Preference.vue:124
 #, fuzzy
 msgid "Save successfully"
@@ -3416,7 +3469,7 @@ msgstr "Directive"
 msgid "Skip Installation"
 msgstr "Install"
 
-#: src/views/certificate/CertificateEditor.vue:211
+#: src/views/certificate/components/CertificateEditor.vue:213
 #, fuzzy
 msgid "SSL Certificate Content"
 msgstr "Certificate Status"
@@ -3430,17 +3483,17 @@ msgstr ""
 msgid "SSL certificate file not found"
 msgstr "Certificate Status"
 
-#: src/views/certificate/CertificateEditor.vue:224
+#: src/views/certificate/components/CertificateEditor.vue:226
 #, fuzzy
 msgid "SSL Certificate Key Content"
 msgstr "Certificate Status"
 
-#: src/views/certificate/CertificateEditor.vue:190
+#: src/views/certificate/components/CertificateEditor.vue:192
 #, fuzzy
 msgid "SSL Certificate Key Path"
 msgstr "Certificate Status"
 
-#: src/views/certificate/CertificateEditor.vue:175
+#: src/views/certificate/components/CertificateEditor.vue:177
 #: src/views/preference/ServerSettings.vue:36
 #, fuzzy
 msgid "SSL Certificate Path"
@@ -3489,7 +3542,7 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/site/site_list/columns.tsx:80 src/views/stream/StreamList.vue:47
+#: src/views/site/site_list/columns.tsx:89 src/views/stream/StreamList.vue:47
 msgid "Status"
 msgstr "Status"
 
@@ -3619,7 +3672,7 @@ msgstr ""
 msgid "Sync strategy"
 msgstr "Certificate is valid"
 
-#: src/views/certificate/CertificateEditor.vue:204
+#: src/views/certificate/components/CertificateEditor.vue:206
 #, fuzzy
 msgid "Sync to"
 msgstr "Certificate is valid"
@@ -3637,7 +3690,7 @@ msgstr ""
 msgid "System Backup"
 msgstr ""
 
-#: src/views/certificate/ACMEUserSelector.vue:88
+#: src/views/certificate/components/ACMEUserSelector.vue:88
 msgid "System Initial User"
 msgstr ""
 
@@ -3688,12 +3741,12 @@ msgid ""
 "dashes, colons, and dots."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:214
+#: src/views/certificate/components/CertificateEditor.vue:216
 #, fuzzy
 msgid "The input is not a SSL Certificate"
 msgstr "Certificate Status"
 
-#: src/views/certificate/CertificateEditor.vue:227
+#: src/views/certificate/components/CertificateEditor.vue:229
 #, fuzzy
 msgid "The input is not a SSL Certificate Key"
 msgstr "Certificate Status"
@@ -3720,12 +3773,12 @@ msgstr ""
 msgid "The parameter of server_name is required"
 msgstr "server_name parameter is required"
 
-#: src/views/certificate/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:181
 #, fuzzy
 msgid "The path exists, but the file is not a certificate"
 msgstr "Certificate Status"
 
-#: src/views/certificate/CertificateEditor.vue:194
+#: src/views/certificate/components/CertificateEditor.vue:196
 #, fuzzy
 msgid "The path exists, but the file is not a private key"
 msgstr "Certificate Status"
@@ -3774,17 +3827,17 @@ msgid ""
 "lose access to your account."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:102
+#: src/views/certificate/components/CertificateEditor.vue:102
 msgid "This Auto Cert item is invalid, please remove it."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:92
+#: src/views/certificate/components/CertificateEditor.vue:92
 msgid "This certificate is managed by Nginx UI"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:163
-#: src/views/certificate/CertificateEditor.vue:177
-#: src/views/certificate/CertificateEditor.vue:192
+#: src/views/certificate/components/CertificateEditor.vue:165
+#: src/views/certificate/components/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:194
 msgid "This field is required"
 msgstr ""
 
@@ -3806,6 +3859,12 @@ msgid ""
 "This field should only contain letters, unicode characters, numbers, and -_."
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:103
+msgid ""
+"This operation will only remove the certificate from the database. The "
+"certificate files on the file system will not be deleted."
+msgstr ""
+
 #: src/views/system/Backup/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -3850,6 +3909,10 @@ msgstr ""
 msgid "Title"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:121
+msgid "To confirm revocation, please type \"Revoke\" in the field below:"
+msgstr ""
+
 #: src/views/preference/components/TOTP.vue:68
 msgid ""
 "To enable it, you need to install the Google or Microsoft Authenticator app "
@@ -3928,7 +3991,7 @@ msgstr "Saved successfully"
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:75
-#: src/views/site/site_list/columns.tsx:110
+#: src/views/site/site_list/columns.tsx:82
 #: src/views/stream/components/RightSettings.vue:99
 #: src/views/stream/StreamList.vue:67 src/views/user/userColumns.tsx:54
 msgid "Updated at"
@@ -4086,6 +4149,10 @@ msgstr ""
 msgid "WebAuthn settings are not configured"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:54
+msgid "WebSocket connection error"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:83
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "

+ 114 - 44
app/src/language/es/app.po

@@ -38,7 +38,7 @@ msgid "Access Logs"
 msgstr "Logs de acceso"
 
 #: src/routes/modules/certificates.ts:20 src/views/certificate/ACMEUser.vue:113
-#: src/views/certificate/ACMEUserSelector.vue:85
+#: src/views/certificate/components/ACMEUserSelector.vue:85
 msgid "ACME User"
 msgstr "Usuario ACME"
 
@@ -52,7 +52,7 @@ msgstr "Usuario ACME"
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
 #: src/views/preference/components/ExternalNotify/columns.ts:46
-#: src/views/site/site_list/columns.tsx:117 src/views/stream/StreamList.vue:74
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/StreamList.vue:74
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Acción"
@@ -286,7 +286,7 @@ msgstr ""
 msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:255
+#: src/views/certificate/components/CertificateEditor.vue:257
 #: src/views/config/ConfigEditor.vue:262 src/views/config/ConfigList.vue:112
 #: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:285
@@ -472,6 +472,12 @@ msgstr "El certificado expiró"
 msgid "Certificate path is empty"
 msgstr "Plantillas de configuración"
 
+#: src/views/certificate/components/RemoveCert.vue:41
+#: src/views/certificate/components/RemoveCert.vue:61
+#, fuzzy
+msgid "Certificate removed successfully"
+msgstr "Limpiado exitoso"
+
 #: src/views/preference/CertSettings.vue:27
 msgid "Certificate Renewal Interval"
 msgstr "Intervalo de renovación del Certificado"
@@ -481,7 +487,7 @@ msgstr "Intervalo de renovación del Certificado"
 msgid "Certificate renewed successfully"
 msgstr "Limpiado exitoso"
 
-#: src/views/certificate/CertificateEditor.vue:128
+#: src/views/certificate/components/CertificateEditor.vue:128
 #: src/views/site/cert/Cert.vue:60
 msgid "Certificate Status"
 msgid_plural "Certificates Status"
@@ -489,7 +495,7 @@ msgstr[0] "Estado del Certificado"
 msgstr[1] "Estado de los Certificados"
 
 #: src/routes/modules/certificates.ts:11
-#: src/views/certificate/CertificateList/Certificate.vue:13
+#: src/views/certificate/CertificateList/Certificate.vue:14
 msgid "Certificates"
 msgstr "Certificados"
 
@@ -789,6 +795,7 @@ msgstr "Descripción"
 
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:21
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
+#: src/views/certificate/components/RemoveCert.vue:87
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
 #: src/views/site/site_list/SiteList.vue:176
@@ -796,6 +803,11 @@ msgstr "Descripción"
 msgid "Delete"
 msgstr "Eliminar"
 
+#: src/views/certificate/components/RemoveCert.vue:92
+#, fuzzy
+msgid "Delete Certificate"
+msgstr "Renovar Certificado"
+
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:35
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:547
 msgid "Delete Permanently"
@@ -978,7 +990,7 @@ msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:159
 #: src/views/site/site_edit/SiteEdit.vue:199
-#: src/views/site/site_list/columns.tsx:102 src/views/stream/StreamEdit.vue:182
+#: src/views/site/site_list/columns.tsx:111 src/views/stream/StreamEdit.vue:182
 #: src/views/stream/StreamList.vue:58 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Desactivado"
@@ -1048,11 +1060,11 @@ msgid_plural "Documents"
 msgstr[0] "Documento de la API"
 msgstr[1] "Documento de la API"
 
-#: src/views/certificate/WildcardCertificate.vue:68
+#: src/views/certificate/components/WildcardCertificate.vue:68
 msgid "Domain"
 msgstr "Dominio"
 
-#: src/views/certificate/CertificateEditor.vue:112
+#: src/views/certificate/components/CertificateEditor.vue:112
 msgid "Domains list is empty, try to reopen Auto Cert for %{config}"
 msgstr ""
 "La lista de dominios está vacía, intente reabrir la certificación automática "
@@ -1226,7 +1238,7 @@ msgstr "Habilitar TLS"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:155
 #: src/views/site/site_edit/SiteEdit.vue:193
-#: src/views/site/site_list/columns.tsx:101
+#: src/views/site/site_list/columns.tsx:110
 #: src/views/stream/components/RightSettings.vue:81
 #: src/views/stream/StreamEdit.vue:176 src/views/stream/StreamList.vue:54
 #: src/views/user/userColumns.tsx:38
@@ -1436,6 +1448,11 @@ msgstr ""
 msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:66
+#, fuzzy
+msgid "Failed to delete certificate"
+msgstr "Falla al obtener el certificado"
+
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:63
 #: src/views/stream/components/RightSettings.vue:45
 #: src/views/stream/StreamList.vue:100
@@ -1554,6 +1571,11 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:48
+#, fuzzy
+msgid "Failed to revoke certificate"
+msgstr "Falla al obtener el certificado"
+
 #: src/views/site/site_edit/SiteEdit.vue:139
 #: src/views/stream/StreamEdit.vue:122
 msgid "Failed to save, syntax error(s) was detected in the configuration."
@@ -1740,6 +1762,15 @@ msgstr ""
 "el máximo de intentos en los minutos del umbral de prohibición, la IP será "
 "bloqueada por un período de tiempo."
 
+#: src/views/site/cert/components/AutoCertStepOne.vue:117
+#, fuzzy
+msgid ""
+"If you want to automatically revoke the old certificate, please enable this "
+"option."
+msgstr ""
+"Si su dominio tiene registros CNAME y no puede obtener certificados, "
+"necesita habilitar esta opción."
+
 #: src/views/preference/components/AddPasskey.vue:70
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr ""
@@ -1753,12 +1784,12 @@ msgstr ""
 "Si su dominio tiene registros CNAME y no puede obtener certificados, "
 "necesita habilitar esta opción."
 
-#: src/views/certificate/CertificateList/Certificate.vue:20
+#: src/views/certificate/CertificateList/Certificate.vue:22
 msgid "Import"
 msgstr "Importar"
 
 #: src/routes/modules/certificates.ts:46
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Import Certificate"
 msgstr "Importar Certificado"
 
@@ -1886,11 +1917,11 @@ msgstr "Código 2FA o de recuperación inválido"
 msgid "IP"
 msgstr "IP"
 
-#: src/views/certificate/CertificateList/Certificate.vue:28
+#: src/views/certificate/CertificateList/Certificate.vue:31
 msgid "Issue wildcard certificate"
 msgstr "Obtener certificado comodín"
 
-#: src/views/certificate/WildcardCertificate.vue:59
+#: src/views/certificate/components/WildcardCertificate.vue:59
 msgid "Issue Wildcard Certificate"
 msgstr "Obtener certificado Comodín"
 
@@ -1956,8 +1987,8 @@ msgstr "Para no modificar dejar en blanco"
 msgid "Leave blank if you don't need this."
 msgstr "Déjelo en blanco si no lo necesita."
 
-#: src/views/certificate/CertificateEditor.vue:220
-#: src/views/certificate/CertificateEditor.vue:233
+#: src/views/certificate/components/CertificateEditor.vue:222
+#: src/views/certificate/components/CertificateEditor.vue:235
 msgid "Leave blank will not change anything"
 msgstr "Dejarlo en blanco no cambiará nada"
 
@@ -2007,7 +2038,7 @@ msgstr "Ubicación"
 msgid "Locations"
 msgstr "Ubicaciones"
 
-#: src/views/certificate/CertificateEditor.vue:243
+#: src/views/certificate/components/CertificateEditor.vue:245
 msgid "Log"
 msgstr "Registro"
 
@@ -2050,7 +2081,7 @@ msgstr ""
 "minutos."
 
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:163
-#: src/views/site/site_list/columns.tsx:103
+#: src/views/site/site_list/columns.tsx:112
 msgid "Maintenance"
 msgstr ""
 
@@ -2126,7 +2157,7 @@ msgid "Modify"
 msgstr "Modificar"
 
 #: src/routes/modules/certificates.ts:36
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Modify Certificate"
 msgstr "Modificar Certificado"
 
@@ -2143,8 +2174,8 @@ msgid "Multi-line Directive"
 msgstr "Directiva multilínea"
 
 #: src/views/certificate/ACMEUser.vue:13
-#: src/views/certificate/CertificateEditor.vue:160
 #: src/views/certificate/CertificateList/certColumns.tsx:10
+#: src/views/certificate/components/CertificateEditor.vue:162
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:305
@@ -2195,7 +2226,7 @@ msgstr "Nueva ruta"
 msgid "New version released"
 msgstr "Se liberó una nueva versión"
 
-#: src/views/certificate/WildcardCertificate.vue:91
+#: src/views/certificate/components/WildcardCertificate.vue:91
 #: src/views/site/cert/components/ObtainCert.vue:211
 #: src/views/site/site_add/SiteAdd.vue:141
 msgid "Next"
@@ -2365,7 +2396,7 @@ msgid "Node"
 msgstr "Nuevo nombre"
 
 #: src/views/site/site_edit/RightSettings.vue:66
-#: src/views/site/site_list/columns.tsx:63
+#: src/views/site/site_list/columns.tsx:65
 #: src/views/stream/components/RightSettings.vue:90
 #: src/views/stream/StreamList.vue:30
 #, fuzzy
@@ -2733,6 +2764,10 @@ msgstr "Seleccione al menos un nodo para actualizar"
 msgid "Please select at least one node to upgrade"
 msgstr "Seleccione al menos un nodo para actualizar"
 
+#: src/views/certificate/components/RemoveCert.vue:27
+msgid "Please type \"Revoke\" to confirm"
+msgstr ""
+
 #: src/views/preference/ServerSettings.vue:21
 #, fuzzy
 msgid "Port"
@@ -3013,8 +3048,8 @@ msgstr "Renombrado con éxito"
 msgid "Renamed successfully"
 msgstr "Renombrado con éxito"
 
-#: src/views/certificate/RenewCert.vue:45
-#: src/views/certificate/RenewCert.vue:49
+#: src/views/certificate/components/RenewCert.vue:45
+#: src/views/certificate/components/RenewCert.vue:49
 msgid "Renew Certificate"
 msgstr "Renovar Certificado"
 
@@ -3026,8 +3061,8 @@ msgstr "Error al renovar el Certificado"
 msgid "Renew Certificate Success"
 msgstr "Renovado de Certificado exitoso"
 
-#: src/views/certificate/RenewCert.vue:27
-#: src/views/certificate/WildcardCertificate.vue:48
+#: src/views/certificate/components/RenewCert.vue:27
+#: src/views/certificate/components/WildcardCertificate.vue:48
 msgid "Renew successfully"
 msgstr "Renovado con éxito"
 
@@ -3113,6 +3148,27 @@ msgstr "Error de análisis de configuración de Nginx"
 msgid "Restore this version"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:26
+#: src/views/certificate/components/RemoveCert.vue:95
+msgid "Revoke"
+msgstr ""
+
+#: src/views/site/cert/components/AutoCertStepOne.vue:114
+#, fuzzy
+msgid "Revoke Old Certificate"
+msgstr "Renovar Certificado"
+
+#: src/views/certificate/components/RemoveCert.vue:109
+#, fuzzy
+msgid "Revoke this certificate"
+msgstr "Renovar Certificado"
+
+#: src/views/certificate/components/RemoveCert.vue:117
+msgid ""
+"Revoking a certificate will affect any services currently using it. This "
+"action cannot be undone."
+msgstr ""
+
 #: src/views/preference/AuthSettings.vue:107
 msgid "RP Display Name"
 msgstr "Nombre RP"
@@ -3136,7 +3192,7 @@ msgstr "Corriendo"
 #: src/components/ChatGPT/ChatGPT.vue:355
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:64
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
-#: src/views/certificate/CertificateEditor.vue:262
+#: src/views/certificate/components/CertificateEditor.vue:264
 #: src/views/config/components/ConfigName.vue:59
 #: src/views/config/ConfigEditor.vue:271
 #: src/views/preference/components/Passkey.vue:130
@@ -3202,7 +3258,7 @@ msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
-#: src/views/certificate/CertificateEditor.vue:49
+#: src/views/certificate/components/CertificateEditor.vue:49
 #: src/views/preference/Preference.vue:124
 msgid "Save successfully"
 msgstr "Guardado con éxito"
@@ -3373,7 +3429,7 @@ msgstr ""
 msgid "Skip Installation"
 msgstr "Instalar"
 
-#: src/views/certificate/CertificateEditor.vue:211
+#: src/views/certificate/components/CertificateEditor.vue:213
 msgid "SSL Certificate Content"
 msgstr "Contenido de certificado SSL"
 
@@ -3386,15 +3442,15 @@ msgstr ""
 msgid "SSL certificate file not found"
 msgstr "Contenido de la llave del certificado SSL"
 
-#: src/views/certificate/CertificateEditor.vue:224
+#: src/views/certificate/components/CertificateEditor.vue:226
 msgid "SSL Certificate Key Content"
 msgstr "Contenido de la llave del certificado SSL"
 
-#: src/views/certificate/CertificateEditor.vue:190
+#: src/views/certificate/components/CertificateEditor.vue:192
 msgid "SSL Certificate Key Path"
 msgstr "Ruta de la llave del certificado SSL"
 
-#: src/views/certificate/CertificateEditor.vue:175
+#: src/views/certificate/components/CertificateEditor.vue:177
 #: src/views/preference/ServerSettings.vue:36
 msgid "SSL Certificate Path"
 msgstr "Ruta del certificado SSL"
@@ -3440,7 +3496,7 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/site/site_list/columns.tsx:80 src/views/stream/StreamList.vue:47
+#: src/views/site/site_list/columns.tsx:89 src/views/stream/StreamList.vue:47
 msgid "Status"
 msgstr "Estado"
 
@@ -3564,7 +3620,7 @@ msgstr "Sincronizar con"
 msgid "Sync strategy"
 msgstr "Sincronizar Certificado"
 
-#: src/views/certificate/CertificateEditor.vue:204
+#: src/views/certificate/components/CertificateEditor.vue:206
 msgid "Sync to"
 msgstr "Sincronizar con"
 
@@ -3582,7 +3638,7 @@ msgstr "Sistema"
 msgid "System Backup"
 msgstr "Sistema"
 
-#: src/views/certificate/ACMEUserSelector.vue:88
+#: src/views/certificate/components/ACMEUserSelector.vue:88
 msgid "System Initial User"
 msgstr "Usuario inicial del sistema"
 
@@ -3638,11 +3694,11 @@ msgstr ""
 "El nombre del modelo solo debe contener letras, unicode, números, guiones, "
 "rayas y puntos."
 
-#: src/views/certificate/CertificateEditor.vue:214
+#: src/views/certificate/components/CertificateEditor.vue:216
 msgid "The input is not a SSL Certificate"
 msgstr "La entrada no es un Certificado SSL"
 
-#: src/views/certificate/CertificateEditor.vue:227
+#: src/views/certificate/components/CertificateEditor.vue:229
 msgid "The input is not a SSL Certificate Key"
 msgstr "La entrada no es una clave de certificado SSL"
 
@@ -3674,11 +3730,11 @@ msgstr ""
 msgid "The parameter of server_name is required"
 msgstr "Se requiere el parámetro server_name"
 
-#: src/views/certificate/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:181
 msgid "The path exists, but the file is not a certificate"
 msgstr "La ruta existe, pero el archivo no es un certificado"
 
-#: src/views/certificate/CertificateEditor.vue:194
+#: src/views/certificate/components/CertificateEditor.vue:196
 msgid "The path exists, but the file is not a private key"
 msgstr "La ruta existe, pero el archivo no es una clave privada"
 
@@ -3730,17 +3786,17 @@ msgid ""
 "lose access to your account."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:102
+#: src/views/certificate/components/CertificateEditor.vue:102
 msgid "This Auto Cert item is invalid, please remove it."
 msgstr "Este elemento de Auto Cert es inválido, elimínelo por favor."
 
-#: src/views/certificate/CertificateEditor.vue:92
+#: src/views/certificate/components/CertificateEditor.vue:92
 msgid "This certificate is managed by Nginx UI"
 msgstr "Este certificado es administrado por Nginx UI"
 
-#: src/views/certificate/CertificateEditor.vue:163
-#: src/views/certificate/CertificateEditor.vue:177
-#: src/views/certificate/CertificateEditor.vue:192
+#: src/views/certificate/components/CertificateEditor.vue:165
+#: src/views/certificate/components/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:194
 msgid "This field is required"
 msgstr "Este campo es obligatorio"
 
@@ -3767,6 +3823,12 @@ msgstr ""
 "El nombre del modelo solo debe contener letras, unicode, números, guiones, "
 "rayas y puntos."
 
+#: src/views/certificate/components/RemoveCert.vue:103
+msgid ""
+"This operation will only remove the certificate from the database. The "
+"certificate files on the file system will not be deleted."
+msgstr ""
+
 #: src/views/system/Backup/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -3812,6 +3874,10 @@ msgstr "Consejos"
 msgid "Title"
 msgstr "Título"
 
+#: src/views/certificate/components/RemoveCert.vue:121
+msgid "To confirm revocation, please type \"Revoke\" in the field below:"
+msgstr ""
+
 #: src/views/preference/components/TOTP.vue:68
 msgid ""
 "To enable it, you need to install the Google or Microsoft Authenticator app "
@@ -3905,7 +3971,7 @@ msgstr "Actualización exitosa"
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:75
-#: src/views/site/site_list/columns.tsx:110
+#: src/views/site/site_list/columns.tsx:82
 #: src/views/stream/components/RightSettings.vue:99
 #: src/views/stream/StreamList.vue:67 src/views/user/userColumns.tsx:54
 msgid "Updated at"
@@ -4059,6 +4125,10 @@ msgstr "Webauthn"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:54
+msgid "WebSocket connection error"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:83
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "

+ 114 - 44
app/src/language/fr_FR/app.po

@@ -36,7 +36,7 @@ msgid "Access Logs"
 msgstr "Journaux d'accès"
 
 #: src/routes/modules/certificates.ts:20 src/views/certificate/ACMEUser.vue:113
-#: src/views/certificate/ACMEUserSelector.vue:85
+#: src/views/certificate/components/ACMEUserSelector.vue:85
 #, fuzzy
 msgid "ACME User"
 msgstr "Nom d'utilisateur"
@@ -51,7 +51,7 @@ msgstr "Nom d'utilisateur"
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
 #: src/views/preference/components/ExternalNotify/columns.ts:46
-#: src/views/site/site_list/columns.tsx:117 src/views/stream/StreamList.vue:74
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/StreamList.vue:74
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Action"
@@ -299,7 +299,7 @@ msgstr ""
 msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:255
+#: src/views/certificate/components/CertificateEditor.vue:257
 #: src/views/config/ConfigEditor.vue:262 src/views/config/ConfigList.vue:112
 #: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:285
@@ -486,6 +486,12 @@ msgstr "Le certificat a expiré"
 msgid "Certificate path is empty"
 msgstr "Modèles de configuration"
 
+#: src/views/certificate/components/RemoveCert.vue:41
+#: src/views/certificate/components/RemoveCert.vue:61
+#, fuzzy
+msgid "Certificate removed successfully"
+msgstr "Désactivé avec succès"
+
 #: src/views/preference/CertSettings.vue:27
 #, fuzzy
 msgid "Certificate Renewal Interval"
@@ -496,7 +502,7 @@ msgstr "Le certificat est valide"
 msgid "Certificate renewed successfully"
 msgstr "Désactivé avec succès"
 
-#: src/views/certificate/CertificateEditor.vue:128
+#: src/views/certificate/components/CertificateEditor.vue:128
 #: src/views/site/cert/Cert.vue:60
 #, fuzzy
 msgid "Certificate Status"
@@ -505,7 +511,7 @@ msgstr[0] "État du certificat"
 msgstr[1] "État du certificat"
 
 #: src/routes/modules/certificates.ts:11
-#: src/views/certificate/CertificateList/Certificate.vue:13
+#: src/views/certificate/CertificateList/Certificate.vue:14
 #, fuzzy
 msgid "Certificates"
 msgstr "État du certificat"
@@ -818,6 +824,7 @@ msgstr "Description"
 
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:21
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
+#: src/views/certificate/components/RemoveCert.vue:87
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
 #: src/views/site/site_list/SiteList.vue:176
@@ -825,6 +832,11 @@ msgstr "Description"
 msgid "Delete"
 msgstr "Supprimer"
 
+#: src/views/certificate/components/RemoveCert.vue:92
+#, fuzzy
+msgid "Delete Certificate"
+msgstr "Changer de certificat"
+
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:35
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:547
 msgid "Delete Permanently"
@@ -1015,7 +1027,7 @@ msgstr "Dupliqué avec succès"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:159
 #: src/views/site/site_edit/SiteEdit.vue:199
-#: src/views/site/site_list/columns.tsx:102 src/views/stream/StreamEdit.vue:182
+#: src/views/site/site_list/columns.tsx:111 src/views/stream/StreamEdit.vue:182
 #: src/views/stream/StreamList.vue:58 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Désactivé"
@@ -1089,11 +1101,11 @@ msgid_plural "Documents"
 msgstr[0] "Jeton d'API"
 msgstr[1] "Jeton d'API"
 
-#: src/views/certificate/WildcardCertificate.vue:68
+#: src/views/certificate/components/WildcardCertificate.vue:68
 msgid "Domain"
 msgstr "Domaine"
 
-#: src/views/certificate/CertificateEditor.vue:112
+#: src/views/certificate/components/CertificateEditor.vue:112
 #, fuzzy
 msgid "Domains list is empty, try to reopen Auto Cert for %{config}"
 msgstr ""
@@ -1274,7 +1286,7 @@ msgstr "Activer TLS"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:155
 #: src/views/site/site_edit/SiteEdit.vue:193
-#: src/views/site/site_list/columns.tsx:101
+#: src/views/site/site_list/columns.tsx:110
 #: src/views/stream/components/RightSettings.vue:81
 #: src/views/stream/StreamEdit.vue:176 src/views/stream/StreamList.vue:54
 #: src/views/user/userColumns.tsx:38
@@ -1489,6 +1501,11 @@ msgstr ""
 msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:66
+#, fuzzy
+msgid "Failed to delete certificate"
+msgstr "Obtenir un certificat"
+
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:63
 #: src/views/stream/components/RightSettings.vue:45
 #: src/views/stream/StreamList.vue:100
@@ -1613,6 +1630,11 @@ msgstr "Erreur lecture nginx.conf"
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr "Erreur lecture nginx.conf"
 
+#: src/views/certificate/components/RemoveCert.vue:48
+#, fuzzy
+msgid "Failed to revoke certificate"
+msgstr "Obtenir un certificat"
+
 #: src/views/site/site_edit/SiteEdit.vue:139
 #: src/views/stream/StreamEdit.vue:122
 msgid "Failed to save, syntax error(s) was detected in the configuration."
@@ -1802,6 +1824,15 @@ msgstr ""
 "atteint le nombre maximum de tentatives en minutes de seuil d'interdiction, "
 "l'adresse IP sera bannie pendant un certain temps."
 
+#: src/views/site/cert/components/AutoCertStepOne.vue:117
+#, fuzzy
+msgid ""
+"If you want to automatically revoke the old certificate, please enable this "
+"option."
+msgstr ""
+"Si votre domaine possède des entrées CNAME et que vous ne pouvez pas obtenir "
+"de certificats, activez cette option."
+
 #: src/views/preference/components/AddPasskey.vue:70
 #, fuzzy
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
@@ -1817,13 +1848,13 @@ msgstr ""
 "Si votre domaine possède des entrées CNAME et que vous ne pouvez pas obtenir "
 "de certificats, activez cette option."
 
-#: src/views/certificate/CertificateList/Certificate.vue:20
+#: src/views/certificate/CertificateList/Certificate.vue:22
 #, fuzzy
 msgid "Import"
 msgstr "Exporter"
 
 #: src/routes/modules/certificates.ts:46
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 #, fuzzy
 msgid "Import Certificate"
 msgstr "État du certificat"
@@ -1953,12 +1984,12 @@ msgstr "Format de la requête invalide"
 msgid "IP"
 msgstr ""
 
-#: src/views/certificate/CertificateList/Certificate.vue:28
+#: src/views/certificate/CertificateList/Certificate.vue:31
 #, fuzzy
 msgid "Issue wildcard certificate"
 msgstr "Obtenir un certificat"
 
-#: src/views/certificate/WildcardCertificate.vue:59
+#: src/views/certificate/components/WildcardCertificate.vue:59
 #, fuzzy
 msgid "Issue Wildcard Certificate"
 msgstr "État du certificat"
@@ -2029,8 +2060,8 @@ msgstr "Laisser vide pour aucun changement"
 msgid "Leave blank if you don't need this."
 msgstr "Laisser vide pour aucun changement"
 
-#: src/views/certificate/CertificateEditor.vue:220
-#: src/views/certificate/CertificateEditor.vue:233
+#: src/views/certificate/components/CertificateEditor.vue:222
+#: src/views/certificate/components/CertificateEditor.vue:235
 #, fuzzy
 msgid "Leave blank will not change anything"
 msgstr "Laisser vide pour aucun changement"
@@ -2087,7 +2118,7 @@ msgstr "Localisation"
 msgid "Locations"
 msgstr "Localisations"
 
-#: src/views/certificate/CertificateEditor.vue:243
+#: src/views/certificate/components/CertificateEditor.vue:245
 #, fuzzy
 msgid "Log"
 msgstr "Connexion"
@@ -2124,7 +2155,7 @@ msgid ""
 msgstr ""
 
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:163
-#: src/views/site/site_list/columns.tsx:103
+#: src/views/site/site_list/columns.tsx:112
 msgid "Maintenance"
 msgstr ""
 
@@ -2204,7 +2235,7 @@ msgid "Modify"
 msgstr "Modifier"
 
 #: src/routes/modules/certificates.ts:36
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 #, fuzzy
 msgid "Modify Certificate"
 msgstr "État du certificat"
@@ -2223,8 +2254,8 @@ msgid "Multi-line Directive"
 msgstr "Directive multiligne"
 
 #: src/views/certificate/ACMEUser.vue:13
-#: src/views/certificate/CertificateEditor.vue:160
 #: src/views/certificate/CertificateList/certColumns.tsx:10
+#: src/views/certificate/components/CertificateEditor.vue:162
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:305
@@ -2277,7 +2308,7 @@ msgstr "Chemin"
 msgid "New version released"
 msgstr "Nouvelle version publiée"
 
-#: src/views/certificate/WildcardCertificate.vue:91
+#: src/views/certificate/components/WildcardCertificate.vue:91
 #: src/views/site/cert/components/ObtainCert.vue:211
 #: src/views/site/site_add/SiteAdd.vue:141
 msgid "Next"
@@ -2449,7 +2480,7 @@ msgid "Node"
 msgstr "Nom d'utilisateur"
 
 #: src/views/site/site_edit/RightSettings.vue:66
-#: src/views/site/site_list/columns.tsx:63
+#: src/views/site/site_list/columns.tsx:65
 #: src/views/stream/components/RightSettings.vue:90
 #: src/views/stream/StreamList.vue:30
 #, fuzzy
@@ -2802,6 +2833,10 @@ msgstr ""
 msgid "Please select at least one node to upgrade"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:27
+msgid "Please type \"Revoke\" to confirm"
+msgstr ""
+
 #: src/views/preference/ServerSettings.vue:21
 #, fuzzy
 msgid "Port"
@@ -3094,8 +3129,8 @@ msgstr "Activé avec succès"
 msgid "Renamed successfully"
 msgstr "Activé avec succès"
 
-#: src/views/certificate/RenewCert.vue:45
-#: src/views/certificate/RenewCert.vue:49
+#: src/views/certificate/components/RenewCert.vue:45
+#: src/views/certificate/components/RenewCert.vue:49
 #, fuzzy
 msgid "Renew Certificate"
 msgstr "Changer de certificat"
@@ -3110,8 +3145,8 @@ msgstr "Changer de certificat"
 msgid "Renew Certificate Success"
 msgstr "Changer de certificat"
 
-#: src/views/certificate/RenewCert.vue:27
-#: src/views/certificate/WildcardCertificate.vue:48
+#: src/views/certificate/components/RenewCert.vue:27
+#: src/views/certificate/components/WildcardCertificate.vue:48
 #, fuzzy
 msgid "Renew successfully"
 msgstr "Activé avec succès"
@@ -3199,6 +3234,27 @@ msgstr "Erreur d'analyse de configuration Nginx"
 msgid "Restore this version"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:26
+#: src/views/certificate/components/RemoveCert.vue:95
+msgid "Revoke"
+msgstr ""
+
+#: src/views/site/cert/components/AutoCertStepOne.vue:114
+#, fuzzy
+msgid "Revoke Old Certificate"
+msgstr "Changer de certificat"
+
+#: src/views/certificate/components/RemoveCert.vue:109
+#, fuzzy
+msgid "Revoke this certificate"
+msgstr "Changer de certificat"
+
+#: src/views/certificate/components/RemoveCert.vue:117
+msgid ""
+"Revoking a certificate will affect any services currently using it. This "
+"action cannot be undone."
+msgstr ""
+
 #: src/views/preference/AuthSettings.vue:107
 msgid "RP Display Name"
 msgstr ""
@@ -3222,7 +3278,7 @@ msgstr "En cours d'éxécution"
 #: src/components/ChatGPT/ChatGPT.vue:355
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:64
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
-#: src/views/certificate/CertificateEditor.vue:262
+#: src/views/certificate/components/CertificateEditor.vue:264
 #: src/views/config/components/ConfigName.vue:59
 #: src/views/config/ConfigEditor.vue:271
 #: src/views/preference/components/Passkey.vue:130
@@ -3288,7 +3344,7 @@ msgstr "Dupliqué avec succès"
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
-#: src/views/certificate/CertificateEditor.vue:49
+#: src/views/certificate/components/CertificateEditor.vue:49
 #: src/views/preference/Preference.vue:124
 msgid "Save successfully"
 msgstr "Sauvegarde réussie"
@@ -3459,7 +3515,7 @@ msgstr "Directive"
 msgid "Skip Installation"
 msgstr "Installer"
 
-#: src/views/certificate/CertificateEditor.vue:211
+#: src/views/certificate/components/CertificateEditor.vue:213
 #, fuzzy
 msgid "SSL Certificate Content"
 msgstr "Contenu de la certification SSL"
@@ -3473,16 +3529,16 @@ msgstr ""
 msgid "SSL certificate file not found"
 msgstr "Contenu de la clé de certification SSL"
 
-#: src/views/certificate/CertificateEditor.vue:224
+#: src/views/certificate/components/CertificateEditor.vue:226
 #, fuzzy
 msgid "SSL Certificate Key Content"
 msgstr "Contenu de la clé de certification SSL"
 
-#: src/views/certificate/CertificateEditor.vue:190
+#: src/views/certificate/components/CertificateEditor.vue:192
 msgid "SSL Certificate Key Path"
 msgstr "Chemin de la clé du certificat SSL"
 
-#: src/views/certificate/CertificateEditor.vue:175
+#: src/views/certificate/components/CertificateEditor.vue:177
 #: src/views/preference/ServerSettings.vue:36
 msgid "SSL Certificate Path"
 msgstr "Chemin du certificat SSL"
@@ -3530,7 +3586,7 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/site/site_list/columns.tsx:80 src/views/stream/StreamList.vue:47
+#: src/views/site/site_list/columns.tsx:89 src/views/stream/StreamList.vue:47
 msgid "Status"
 msgstr "Statut"
 
@@ -3661,7 +3717,7 @@ msgstr ""
 msgid "Sync strategy"
 msgstr "Changer de certificat"
 
-#: src/views/certificate/CertificateEditor.vue:204
+#: src/views/certificate/components/CertificateEditor.vue:206
 #, fuzzy
 msgid "Sync to"
 msgstr "Changer de certificat"
@@ -3680,7 +3736,7 @@ msgstr "Système"
 msgid "System Backup"
 msgstr "Système"
 
-#: src/views/certificate/ACMEUserSelector.vue:88
+#: src/views/certificate/components/ACMEUserSelector.vue:88
 msgid "System Initial User"
 msgstr ""
 
@@ -3732,12 +3788,12 @@ msgid ""
 "dashes, colons, and dots."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:214
+#: src/views/certificate/components/CertificateEditor.vue:216
 #, fuzzy
 msgid "The input is not a SSL Certificate"
 msgstr "Chemin de la clé du certificat SSL"
 
-#: src/views/certificate/CertificateEditor.vue:227
+#: src/views/certificate/components/CertificateEditor.vue:229
 #, fuzzy
 msgid "The input is not a SSL Certificate Key"
 msgstr "Chemin de la clé du certificat SSL"
@@ -3764,12 +3820,12 @@ msgstr ""
 msgid "The parameter of server_name is required"
 msgstr "Le paramètre server_name est obligatoire"
 
-#: src/views/certificate/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:181
 #, fuzzy
 msgid "The path exists, but the file is not a certificate"
 msgstr "Chemin de la clé du certificat SSL"
 
-#: src/views/certificate/CertificateEditor.vue:194
+#: src/views/certificate/components/CertificateEditor.vue:196
 #, fuzzy
 msgid "The path exists, but the file is not a private key"
 msgstr "Chemin de la clé du certificat SSL"
@@ -3818,20 +3874,20 @@ msgid ""
 "lose access to your account."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:102
+#: src/views/certificate/components/CertificateEditor.vue:102
 #, fuzzy
 msgid "This Auto Cert item is invalid, please remove it."
 msgstr ""
 "Cet élément de certification automatique n'est pas valide, veuillez le "
 "supprimer."
 
-#: src/views/certificate/CertificateEditor.vue:92
+#: src/views/certificate/components/CertificateEditor.vue:92
 msgid "This certificate is managed by Nginx UI"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:163
-#: src/views/certificate/CertificateEditor.vue:177
-#: src/views/certificate/CertificateEditor.vue:192
+#: src/views/certificate/components/CertificateEditor.vue:165
+#: src/views/certificate/components/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:194
 msgid "This field is required"
 msgstr ""
 
@@ -3853,6 +3909,12 @@ msgid ""
 "This field should only contain letters, unicode characters, numbers, and -_."
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:103
+msgid ""
+"This operation will only remove the certificate from the database. The "
+"certificate files on the file system will not be deleted."
+msgstr ""
+
 #: src/views/system/Backup/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -3897,6 +3959,10 @@ msgstr ""
 msgid "Title"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:121
+msgid "To confirm revocation, please type \"Revoke\" in the field below:"
+msgstr ""
+
 #: src/views/preference/components/TOTP.vue:68
 msgid ""
 "To enable it, you need to install the Google or Microsoft Authenticator app "
@@ -3979,7 +4045,7 @@ msgstr "Mis à jour avec succés"
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:75
-#: src/views/site/site_list/columns.tsx:110
+#: src/views/site/site_list/columns.tsx:82
 #: src/views/stream/components/RightSettings.vue:99
 #: src/views/stream/StreamList.vue:67 src/views/user/userColumns.tsx:54
 msgid "Updated at"
@@ -4135,6 +4201,10 @@ msgstr ""
 msgid "WebAuthn settings are not configured"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:54
+msgid "WebSocket connection error"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:83
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "

+ 111 - 44
app/src/language/ko_KR/app.po

@@ -36,7 +36,7 @@ msgid "Access Logs"
 msgstr "접근 로그"
 
 #: src/routes/modules/certificates.ts:20 src/views/certificate/ACMEUser.vue:113
-#: src/views/certificate/ACMEUserSelector.vue:85
+#: src/views/certificate/components/ACMEUserSelector.vue:85
 msgid "ACME User"
 msgstr "ACME 사용자"
 
@@ -50,7 +50,7 @@ msgstr "ACME 사용자"
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
 #: src/views/preference/components/ExternalNotify/columns.ts:46
-#: src/views/site/site_list/columns.tsx:117 src/views/stream/StreamList.vue:74
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/StreamList.vue:74
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "작업"
@@ -276,7 +276,7 @@ msgstr "자동 재시작"
 msgid "Automatically indexed from site and stream configurations."
 msgstr "사이트 및 스트림 구성에서 자동으로 색인됩니다."
 
-#: src/views/certificate/CertificateEditor.vue:255
+#: src/views/certificate/components/CertificateEditor.vue:257
 #: src/views/config/ConfigEditor.vue:262 src/views/config/ConfigList.vue:112
 #: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:285
@@ -460,6 +460,12 @@ msgstr "인증서가 만료되었습니다"
 msgid "Certificate path is empty"
 msgstr "구성 템플릿"
 
+#: src/views/certificate/components/RemoveCert.vue:41
+#: src/views/certificate/components/RemoveCert.vue:61
+#, fuzzy
+msgid "Certificate removed successfully"
+msgstr "성공적으로 제거됨"
+
 #: src/views/preference/CertSettings.vue:27
 msgid "Certificate Renewal Interval"
 msgstr "인증서 갱신 간격"
@@ -469,7 +475,7 @@ msgstr "인증서 갱신 간격"
 msgid "Certificate renewed successfully"
 msgstr "성공적으로 제거됨"
 
-#: src/views/certificate/CertificateEditor.vue:128
+#: src/views/certificate/components/CertificateEditor.vue:128
 #: src/views/site/cert/Cert.vue:60
 msgid "Certificate Status"
 msgid_plural "Certificates Status"
@@ -477,7 +483,7 @@ msgstr[0] "인증서 상태"
 msgstr[1] "인증서 상태"
 
 #: src/routes/modules/certificates.ts:11
-#: src/views/certificate/CertificateList/Certificate.vue:13
+#: src/views/certificate/CertificateList/Certificate.vue:14
 msgid "Certificates"
 msgstr "인증서"
 
@@ -778,6 +784,7 @@ msgstr "설명"
 
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:21
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
+#: src/views/certificate/components/RemoveCert.vue:87
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
 #: src/views/site/site_list/SiteList.vue:176
@@ -785,6 +792,11 @@ msgstr "설명"
 msgid "Delete"
 msgstr "삭제"
 
+#: src/views/certificate/components/RemoveCert.vue:92
+#, fuzzy
+msgid "Delete Certificate"
+msgstr "인증서 갱신"
+
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:35
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:547
 msgid "Delete Permanently"
@@ -971,7 +983,7 @@ msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:159
 #: src/views/site/site_edit/SiteEdit.vue:199
-#: src/views/site/site_list/columns.tsx:102 src/views/stream/StreamEdit.vue:182
+#: src/views/site/site_list/columns.tsx:111 src/views/stream/StreamEdit.vue:182
 #: src/views/stream/StreamList.vue:58 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "비활성화됨"
@@ -1041,11 +1053,11 @@ msgid_plural "Documents"
 msgstr[0] "API 문서"
 msgstr[1] "API 문서"
 
-#: src/views/certificate/WildcardCertificate.vue:68
+#: src/views/certificate/components/WildcardCertificate.vue:68
 msgid "Domain"
 msgstr "도메인"
 
-#: src/views/certificate/CertificateEditor.vue:112
+#: src/views/certificate/components/CertificateEditor.vue:112
 msgid "Domains list is empty, try to reopen Auto Cert for %{config}"
 msgstr ""
 "도메인 목록이 비어 있습니다. %{config}에 대한 자동 인증서를 다시 열어보세요"
@@ -1217,7 +1229,7 @@ msgstr "TLS 활성화"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:155
 #: src/views/site/site_edit/SiteEdit.vue:193
-#: src/views/site/site_list/columns.tsx:101
+#: src/views/site/site_list/columns.tsx:110
 #: src/views/stream/components/RightSettings.vue:81
 #: src/views/stream/StreamEdit.vue:176 src/views/stream/StreamList.vue:54
 #: src/views/user/userColumns.tsx:38
@@ -1430,6 +1442,11 @@ msgstr ""
 msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:66
+#, fuzzy
+msgid "Failed to delete certificate"
+msgstr "인증서 획득 실패"
+
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:63
 #: src/views/stream/components/RightSettings.vue:45
 #: src/views/stream/StreamList.vue:100
@@ -1548,6 +1565,11 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:48
+#, fuzzy
+msgid "Failed to revoke certificate"
+msgstr "인증서 획득 실패"
+
 #: src/views/site/site_edit/SiteEdit.vue:139
 #: src/views/stream/StreamEdit.vue:122
 msgid "Failed to save, syntax error(s) was detected in the configuration."
@@ -1730,6 +1752,12 @@ msgid ""
 "ban threshold minutes, the ip will be banned for a period of time."
 msgstr ""
 
+#: src/views/site/cert/components/AutoCertStepOne.vue:117
+msgid ""
+"If you want to automatically revoke the old certificate, please enable this "
+"option."
+msgstr ""
+
 #: src/views/preference/components/AddPasskey.vue:70
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr ""
@@ -1740,12 +1768,12 @@ msgid ""
 "need to enable this option."
 msgstr ""
 
-#: src/views/certificate/CertificateList/Certificate.vue:20
+#: src/views/certificate/CertificateList/Certificate.vue:22
 msgid "Import"
 msgstr "가져오기"
 
 #: src/routes/modules/certificates.ts:46
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 #, fuzzy
 msgid "Import Certificate"
 msgstr "인증서 상태"
@@ -1875,12 +1903,12 @@ msgstr ""
 msgid "IP"
 msgstr ""
 
-#: src/views/certificate/CertificateList/Certificate.vue:28
+#: src/views/certificate/CertificateList/Certificate.vue:31
 #, fuzzy
 msgid "Issue wildcard certificate"
 msgstr "인증서 유효"
 
-#: src/views/certificate/WildcardCertificate.vue:59
+#: src/views/certificate/components/WildcardCertificate.vue:59
 #, fuzzy
 msgid "Issue Wildcard Certificate"
 msgstr "인증서 상태"
@@ -1949,8 +1977,8 @@ msgstr "Leave blank for no change"
 msgid "Leave blank if you don't need this."
 msgstr "Leave blank for no change"
 
-#: src/views/certificate/CertificateEditor.vue:220
-#: src/views/certificate/CertificateEditor.vue:233
+#: src/views/certificate/components/CertificateEditor.vue:222
+#: src/views/certificate/components/CertificateEditor.vue:235
 #, fuzzy
 msgid "Leave blank will not change anything"
 msgstr "변경사항이 없으면 비워두세요"
@@ -2005,7 +2033,7 @@ msgstr "위치"
 msgid "Locations"
 msgstr "위치들"
 
-#: src/views/certificate/CertificateEditor.vue:243
+#: src/views/certificate/components/CertificateEditor.vue:245
 #, fuzzy
 msgid "Log"
 msgstr "로그인"
@@ -2046,7 +2074,7 @@ msgstr ""
 "(분 단위)에서 logrotate 명령을 실행합니다."
 
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:163
-#: src/views/site/site_list/columns.tsx:103
+#: src/views/site/site_list/columns.tsx:112
 msgid "Maintenance"
 msgstr ""
 
@@ -2127,7 +2155,7 @@ msgid "Modify"
 msgstr "설정 수정"
 
 #: src/routes/modules/certificates.ts:36
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 #, fuzzy
 msgid "Modify Certificate"
 msgstr "인증서 상태"
@@ -2147,8 +2175,8 @@ msgid "Multi-line Directive"
 msgstr "단일 지시문"
 
 #: src/views/certificate/ACMEUser.vue:13
-#: src/views/certificate/CertificateEditor.vue:160
 #: src/views/certificate/CertificateList/certColumns.tsx:10
+#: src/views/certificate/components/CertificateEditor.vue:162
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:305
@@ -2201,7 +2229,7 @@ msgstr "경로"
 msgid "New version released"
 msgstr "새 버전 출시"
 
-#: src/views/certificate/WildcardCertificate.vue:91
+#: src/views/certificate/components/WildcardCertificate.vue:91
 #: src/views/site/cert/components/ObtainCert.vue:211
 #: src/views/site/site_add/SiteAdd.vue:141
 msgid "Next"
@@ -2373,7 +2401,7 @@ msgid "Node"
 msgstr "이름 변경"
 
 #: src/views/site/site_edit/RightSettings.vue:66
-#: src/views/site/site_list/columns.tsx:63
+#: src/views/site/site_list/columns.tsx:65
 #: src/views/stream/components/RightSettings.vue:90
 #: src/views/stream/StreamList.vue:30
 #, fuzzy
@@ -2726,6 +2754,10 @@ msgstr "적어도 하나의 노드를 선택해주세요!"
 msgid "Please select at least one node to upgrade"
 msgstr "적어도 하나의 노드를 선택해주세요!"
 
+#: src/views/certificate/components/RemoveCert.vue:27
+msgid "Please type \"Revoke\" to confirm"
+msgstr ""
+
 #: src/views/preference/ServerSettings.vue:21
 #, fuzzy
 msgid "Port"
@@ -3017,8 +3049,8 @@ msgstr "성공적으로 갱신됨"
 msgid "Renamed successfully"
 msgstr "성공적으로 갱신됨"
 
-#: src/views/certificate/RenewCert.vue:45
-#: src/views/certificate/RenewCert.vue:49
+#: src/views/certificate/components/RenewCert.vue:45
+#: src/views/certificate/components/RenewCert.vue:49
 #, fuzzy
 msgid "Renew Certificate"
 msgstr "인증서 갱신"
@@ -3033,8 +3065,8 @@ msgstr "인증서 갱신 오류"
 msgid "Renew Certificate Success"
 msgstr "인증서 갱신 성공"
 
-#: src/views/certificate/RenewCert.vue:27
-#: src/views/certificate/WildcardCertificate.vue:48
+#: src/views/certificate/components/RenewCert.vue:27
+#: src/views/certificate/components/WildcardCertificate.vue:48
 #, fuzzy
 msgid "Renew successfully"
 msgstr "성공적으로 갱신됨"
@@ -3122,6 +3154,27 @@ msgstr "Nginx 구성 오류름"
 msgid "Restore this version"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:26
+#: src/views/certificate/components/RemoveCert.vue:95
+msgid "Revoke"
+msgstr ""
+
+#: src/views/site/cert/components/AutoCertStepOne.vue:114
+#, fuzzy
+msgid "Revoke Old Certificate"
+msgstr "인증서 갱신"
+
+#: src/views/certificate/components/RemoveCert.vue:109
+#, fuzzy
+msgid "Revoke this certificate"
+msgstr "인증서 갱신"
+
+#: src/views/certificate/components/RemoveCert.vue:117
+msgid ""
+"Revoking a certificate will affect any services currently using it. This "
+"action cannot be undone."
+msgstr ""
+
 #: src/views/preference/AuthSettings.vue:107
 msgid "RP Display Name"
 msgstr ""
@@ -3146,7 +3199,7 @@ msgstr "실행 중"
 #: src/components/ChatGPT/ChatGPT.vue:355
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:64
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
-#: src/views/certificate/CertificateEditor.vue:262
+#: src/views/certificate/components/CertificateEditor.vue:264
 #: src/views/config/components/ConfigName.vue:59
 #: src/views/config/ConfigEditor.vue:271
 #: src/views/preference/components/Passkey.vue:130
@@ -3212,7 +3265,7 @@ msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
-#: src/views/certificate/CertificateEditor.vue:49
+#: src/views/certificate/components/CertificateEditor.vue:49
 #: src/views/preference/Preference.vue:124
 #, fuzzy
 msgid "Save successfully"
@@ -3380,7 +3433,7 @@ msgstr ""
 msgid "Skip Installation"
 msgstr "설치"
 
-#: src/views/certificate/CertificateEditor.vue:211
+#: src/views/certificate/components/CertificateEditor.vue:213
 #, fuzzy
 msgid "SSL Certificate Content"
 msgstr "인증서 상태"
@@ -3394,16 +3447,16 @@ msgstr ""
 msgid "SSL certificate file not found"
 msgstr "SSL 인증서키 콘텐츠"
 
-#: src/views/certificate/CertificateEditor.vue:224
+#: src/views/certificate/components/CertificateEditor.vue:226
 msgid "SSL Certificate Key Content"
 msgstr "SSL 인증서키 콘텐츠"
 
-#: src/views/certificate/CertificateEditor.vue:190
+#: src/views/certificate/components/CertificateEditor.vue:192
 #, fuzzy
 msgid "SSL Certificate Key Path"
 msgstr "SSL 인증서 키 경로"
 
-#: src/views/certificate/CertificateEditor.vue:175
+#: src/views/certificate/components/CertificateEditor.vue:177
 #: src/views/preference/ServerSettings.vue:36
 #, fuzzy
 msgid "SSL Certificate Path"
@@ -3452,7 +3505,7 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/site/site_list/columns.tsx:80 src/views/stream/StreamList.vue:47
+#: src/views/site/site_list/columns.tsx:89 src/views/stream/StreamList.vue:47
 msgid "Status"
 msgstr "상태"
 
@@ -3581,7 +3634,7 @@ msgstr ""
 msgid "Sync strategy"
 msgstr "인증서 갱신"
 
-#: src/views/certificate/CertificateEditor.vue:204
+#: src/views/certificate/components/CertificateEditor.vue:206
 msgid "Sync to"
 msgstr ""
 
@@ -3599,7 +3652,7 @@ msgstr "시스템"
 msgid "System Backup"
 msgstr "시스템"
 
-#: src/views/certificate/ACMEUserSelector.vue:88
+#: src/views/certificate/components/ACMEUserSelector.vue:88
 msgid "System Initial User"
 msgstr ""
 
@@ -3651,11 +3704,11 @@ msgid ""
 "dashes, colons, and dots."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:214
+#: src/views/certificate/components/CertificateEditor.vue:216
 msgid "The input is not a SSL Certificate"
 msgstr "입력이 SSL 인증서가 아닙니다"
 
-#: src/views/certificate/CertificateEditor.vue:227
+#: src/views/certificate/components/CertificateEditor.vue:229
 #, fuzzy
 msgid "The input is not a SSL Certificate Key"
 msgstr "Certificate Status"
@@ -3682,12 +3735,12 @@ msgstr ""
 msgid "The parameter of server_name is required"
 msgstr "server_name 매개변수가 필요합니다"
 
-#: src/views/certificate/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:181
 #, fuzzy
 msgid "The path exists, but the file is not a certificate"
 msgstr "Certificate Status"
 
-#: src/views/certificate/CertificateEditor.vue:194
+#: src/views/certificate/components/CertificateEditor.vue:196
 msgid "The path exists, but the file is not a private key"
 msgstr "경로는 존재하지만 파일은 개인 키가 아닙니다"
 
@@ -3736,17 +3789,17 @@ msgid ""
 "lose access to your account."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:102
+#: src/views/certificate/components/CertificateEditor.vue:102
 msgid "This Auto Cert item is invalid, please remove it."
 msgstr "이 자동 인증 항목이 유효하지 않습니다. 제거해주세요."
 
-#: src/views/certificate/CertificateEditor.vue:92
+#: src/views/certificate/components/CertificateEditor.vue:92
 msgid "This certificate is managed by Nginx UI"
 msgstr "이 인증서는 Nginx UI에서 관리됩니다"
 
-#: src/views/certificate/CertificateEditor.vue:163
-#: src/views/certificate/CertificateEditor.vue:177
-#: src/views/certificate/CertificateEditor.vue:192
+#: src/views/certificate/components/CertificateEditor.vue:165
+#: src/views/certificate/components/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:194
 msgid "This field is required"
 msgstr "이 필드는 필수입니다"
 
@@ -3770,6 +3823,12 @@ msgid ""
 "This field should only contain letters, unicode characters, numbers, and -_."
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:103
+msgid ""
+"This operation will only remove the certificate from the database. The "
+"certificate files on the file system will not be deleted."
+msgstr ""
+
 #: src/views/system/Backup/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -3813,6 +3872,10 @@ msgstr "팁"
 msgid "Title"
 msgstr "제목"
 
+#: src/views/certificate/components/RemoveCert.vue:121
+msgid "To confirm revocation, please type \"Revoke\" in the field below:"
+msgstr ""
+
 #: src/views/preference/components/TOTP.vue:68
 msgid ""
 "To enable it, you need to install the Google or Microsoft Authenticator app "
@@ -3894,7 +3957,7 @@ msgstr "성공적으로 저장되었습니다"
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:75
-#: src/views/site/site_list/columns.tsx:110
+#: src/views/site/site_list/columns.tsx:82
 #: src/views/stream/components/RightSettings.vue:99
 #: src/views/stream/StreamList.vue:67 src/views/user/userColumns.tsx:54
 msgid "Updated at"
@@ -4055,6 +4118,10 @@ msgstr ""
 msgid "WebAuthn settings are not configured"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:54
+msgid "WebSocket connection error"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:83
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "

+ 99 - 44
app/src/language/messages.pot

@@ -25,7 +25,7 @@ msgstr ""
 
 #: src/routes/modules/certificates.ts:20
 #: src/views/certificate/ACMEUser.vue:113
-#: src/views/certificate/ACMEUserSelector.vue:85
+#: src/views/certificate/components/ACMEUserSelector.vue:85
 msgid "ACME User"
 msgstr ""
 
@@ -39,7 +39,7 @@ msgstr ""
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
 #: src/views/preference/components/ExternalNotify/columns.ts:46
-#: src/views/site/site_list/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:120
 #: src/views/stream/StreamList.vue:74
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
@@ -266,7 +266,7 @@ msgstr ""
 msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:255
+#: src/views/certificate/components/CertificateEditor.vue:257
 #: src/views/config/ConfigEditor.vue:262
 #: src/views/config/ConfigList.vue:112
 #: src/views/config/ConfigList.vue:195
@@ -439,6 +439,11 @@ msgstr ""
 msgid "Certificate path is empty"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:41
+#: src/views/certificate/components/RemoveCert.vue:61
+msgid "Certificate removed successfully"
+msgstr ""
+
 #: src/views/preference/CertSettings.vue:27
 msgid "Certificate Renewal Interval"
 msgstr ""
@@ -447,7 +452,7 @@ msgstr ""
 msgid "Certificate renewed successfully"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:128
+#: src/views/certificate/components/CertificateEditor.vue:128
 #: src/views/site/cert/Cert.vue:60
 msgid "Certificate Status"
 msgid_plural "Certificates Status"
@@ -455,7 +460,7 @@ msgstr[0] ""
 msgstr[1] ""
 
 #: src/routes/modules/certificates.ts:11
-#: src/views/certificate/CertificateList/Certificate.vue:13
+#: src/views/certificate/CertificateList/Certificate.vue:14
 msgid "Certificates"
 msgstr ""
 
@@ -738,6 +743,7 @@ msgstr ""
 
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:21
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
+#: src/views/certificate/components/RemoveCert.vue:87
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
 #: src/views/site/site_list/SiteList.vue:176
@@ -745,6 +751,10 @@ msgstr ""
 msgid "Delete"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:92
+msgid "Delete Certificate"
+msgstr ""
+
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:35
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:547
 msgid "Delete Permanently"
@@ -915,7 +925,7 @@ msgstr ""
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:159
 #: src/views/site/site_edit/SiteEdit.vue:199
-#: src/views/site/site_list/columns.tsx:102
+#: src/views/site/site_list/columns.tsx:111
 #: src/views/stream/StreamEdit.vue:182
 #: src/views/stream/StreamList.vue:58
 #: src/views/user/userColumns.tsx:41
@@ -985,11 +995,11 @@ msgid_plural "Documents"
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/views/certificate/WildcardCertificate.vue:68
+#: src/views/certificate/components/WildcardCertificate.vue:68
 msgid "Domain"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:112
+#: src/views/certificate/components/CertificateEditor.vue:112
 msgid "Domains list is empty, try to reopen Auto Cert for %{config}"
 msgstr ""
 
@@ -1143,7 +1153,7 @@ msgstr ""
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:155
 #: src/views/site/site_edit/SiteEdit.vue:193
-#: src/views/site/site_list/columns.tsx:101
+#: src/views/site/site_list/columns.tsx:110
 #: src/views/stream/components/RightSettings.vue:81
 #: src/views/stream/StreamEdit.vue:176
 #: src/views/stream/StreamList.vue:54
@@ -1337,6 +1347,10 @@ msgstr ""
 msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:66
+msgid "Failed to delete certificate"
+msgstr ""
+
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:63
 #: src/views/stream/components/RightSettings.vue:45
 #: src/views/stream/StreamList.vue:100
@@ -1441,6 +1455,10 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:48
+msgid "Failed to revoke certificate"
+msgstr ""
+
 #: src/views/site/site_edit/SiteEdit.vue:139
 #: src/views/stream/StreamEdit.vue:122
 msgid "Failed to save, syntax error(s) was detected in the configuration."
@@ -1608,6 +1626,10 @@ msgstr ""
 msgid "If the number of login failed attempts from a ip reach the max attempts in ban threshold minutes, the ip will be banned for a period of time."
 msgstr ""
 
+#: src/views/site/cert/components/AutoCertStepOne.vue:117
+msgid "If you want to automatically revoke the old certificate, please enable this option."
+msgstr ""
+
 #: src/views/preference/components/AddPasskey.vue:70
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr ""
@@ -1616,12 +1638,12 @@ msgstr ""
 msgid "If your domain has CNAME records and you cannot obtain certificates, you need to enable this option."
 msgstr ""
 
-#: src/views/certificate/CertificateList/Certificate.vue:20
+#: src/views/certificate/CertificateList/Certificate.vue:22
 msgid "Import"
 msgstr ""
 
 #: src/routes/modules/certificates.ts:46
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Import Certificate"
 msgstr ""
 
@@ -1743,11 +1765,11 @@ msgstr ""
 msgid "IP"
 msgstr ""
 
-#: src/views/certificate/CertificateList/Certificate.vue:28
+#: src/views/certificate/CertificateList/Certificate.vue:31
 msgid "Issue wildcard certificate"
 msgstr ""
 
-#: src/views/certificate/WildcardCertificate.vue:59
+#: src/views/certificate/components/WildcardCertificate.vue:59
 msgid "Issue Wildcard Certificate"
 msgstr ""
 
@@ -1808,8 +1830,8 @@ msgstr ""
 msgid "Leave blank if you don't need this."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:220
-#: src/views/certificate/CertificateEditor.vue:233
+#: src/views/certificate/components/CertificateEditor.vue:222
+#: src/views/certificate/components/CertificateEditor.vue:235
 msgid "Leave blank will not change anything"
 msgstr ""
 
@@ -1859,7 +1881,7 @@ msgstr ""
 msgid "Locations"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:243
+#: src/views/certificate/components/CertificateEditor.vue:245
 msgid "Log"
 msgstr ""
 
@@ -1891,7 +1913,7 @@ msgid "Logrotate, by default, is enabled in most mainstream Linux distributions
 msgstr ""
 
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:163
-#: src/views/site/site_list/columns.tsx:103
+#: src/views/site/site_list/columns.tsx:112
 msgid "Maintenance"
 msgstr ""
 
@@ -1966,7 +1988,7 @@ msgid "Modify"
 msgstr ""
 
 #: src/routes/modules/certificates.ts:36
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Modify Certificate"
 msgstr ""
 
@@ -1983,8 +2005,8 @@ msgid "Multi-line Directive"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:13
-#: src/views/certificate/CertificateEditor.vue:160
 #: src/views/certificate/CertificateList/certColumns.tsx:10
+#: src/views/certificate/components/CertificateEditor.vue:162
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7
@@ -2036,7 +2058,7 @@ msgstr ""
 msgid "New version released"
 msgstr ""
 
-#: src/views/certificate/WildcardCertificate.vue:91
+#: src/views/certificate/components/WildcardCertificate.vue:91
 #: src/views/site/cert/components/ObtainCert.vue:211
 #: src/views/site/site_add/SiteAdd.vue:141
 msgid "Next"
@@ -2193,7 +2215,7 @@ msgid "Node"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:66
-#: src/views/site/site_list/columns.tsx:63
+#: src/views/site/site_list/columns.tsx:65
 #: src/views/stream/components/RightSettings.vue:90
 #: src/views/stream/StreamList.vue:30
 msgid "Node Group"
@@ -2512,6 +2534,10 @@ msgstr ""
 msgid "Please select at least one node to upgrade"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:27
+msgid "Please type \"Revoke\" to confirm"
+msgstr ""
+
 #: src/views/preference/ServerSettings.vue:21
 msgid "Port"
 msgstr ""
@@ -2769,8 +2795,8 @@ msgstr ""
 msgid "Renamed successfully"
 msgstr ""
 
-#: src/views/certificate/RenewCert.vue:45
-#: src/views/certificate/RenewCert.vue:49
+#: src/views/certificate/components/RenewCert.vue:45
+#: src/views/certificate/components/RenewCert.vue:49
 msgid "Renew Certificate"
 msgstr ""
 
@@ -2782,8 +2808,8 @@ msgstr ""
 msgid "Renew Certificate Success"
 msgstr ""
 
-#: src/views/certificate/RenewCert.vue:27
-#: src/views/certificate/WildcardCertificate.vue:48
+#: src/views/certificate/components/RenewCert.vue:27
+#: src/views/certificate/components/WildcardCertificate.vue:48
 msgid "Renew successfully"
 msgstr ""
 
@@ -2860,6 +2886,23 @@ msgstr ""
 msgid "Restore this version"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:26
+#: src/views/certificate/components/RemoveCert.vue:95
+msgid "Revoke"
+msgstr ""
+
+#: src/views/site/cert/components/AutoCertStepOne.vue:114
+msgid "Revoke Old Certificate"
+msgstr ""
+
+#: src/views/certificate/components/RemoveCert.vue:109
+msgid "Revoke this certificate"
+msgstr ""
+
+#: src/views/certificate/components/RemoveCert.vue:117
+msgid "Revoking a certificate will affect any services currently using it. This action cannot be undone."
+msgstr ""
+
 #: src/views/preference/AuthSettings.vue:107
 msgid "RP Display Name"
 msgstr ""
@@ -2883,7 +2926,7 @@ msgstr ""
 #: src/components/ChatGPT/ChatGPT.vue:355
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:64
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
-#: src/views/certificate/CertificateEditor.vue:262
+#: src/views/certificate/components/CertificateEditor.vue:264
 #: src/views/config/components/ConfigName.vue:59
 #: src/views/config/ConfigEditor.vue:271
 #: src/views/preference/components/Passkey.vue:130
@@ -2941,7 +2984,7 @@ msgstr ""
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
-#: src/views/certificate/CertificateEditor.vue:49
+#: src/views/certificate/components/CertificateEditor.vue:49
 #: src/views/preference/Preference.vue:124
 msgid "Save successfully"
 msgstr ""
@@ -3093,7 +3136,7 @@ msgstr ""
 msgid "Skip Installation"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:211
+#: src/views/certificate/components/CertificateEditor.vue:213
 msgid "SSL Certificate Content"
 msgstr ""
 
@@ -3105,15 +3148,15 @@ msgstr ""
 msgid "SSL certificate file not found"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:224
+#: src/views/certificate/components/CertificateEditor.vue:226
 msgid "SSL Certificate Key Content"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:190
+#: src/views/certificate/components/CertificateEditor.vue:192
 msgid "SSL Certificate Key Path"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:175
+#: src/views/certificate/components/CertificateEditor.vue:177
 #: src/views/preference/ServerSettings.vue:36
 msgid "SSL Certificate Path"
 msgstr ""
@@ -3158,7 +3201,7 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/site/site_list/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:89
 #: src/views/stream/StreamList.vue:47
 msgid "Status"
 msgstr ""
@@ -3275,7 +3318,7 @@ msgstr ""
 msgid "Sync strategy"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:204
+#: src/views/certificate/components/CertificateEditor.vue:206
 msgid "Sync to"
 msgstr ""
 
@@ -3292,7 +3335,7 @@ msgstr ""
 msgid "System Backup"
 msgstr ""
 
-#: src/views/certificate/ACMEUserSelector.vue:88
+#: src/views/certificate/components/ACMEUserSelector.vue:88
 msgid "System Initial User"
 msgstr ""
 
@@ -3335,11 +3378,11 @@ msgstr ""
 msgid "The ICP Number should only contain letters, unicode, numbers, hyphens, dashes, colons, and dots."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:214
+#: src/views/certificate/components/CertificateEditor.vue:216
 msgid "The input is not a SSL Certificate"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:227
+#: src/views/certificate/components/CertificateEditor.vue:229
 msgid "The input is not a SSL Certificate Key"
 msgstr ""
 
@@ -3359,11 +3402,11 @@ msgstr ""
 msgid "The parameter of server_name is required"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:181
 msgid "The path exists, but the file is not a certificate"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:194
+#: src/views/certificate/components/CertificateEditor.vue:196
 msgid "The path exists, but the file is not a private key"
 msgstr ""
 
@@ -3397,17 +3440,17 @@ msgstr ""
 msgid "These codes are the last resort for accessing your account in case you lose your password and second factors. If you cannot find these codes, you will lose access to your account."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:102
+#: src/views/certificate/components/CertificateEditor.vue:102
 msgid "This Auto Cert item is invalid, please remove it."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:92
+#: src/views/certificate/components/CertificateEditor.vue:92
 msgid "This certificate is managed by Nginx UI"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:163
-#: src/views/certificate/CertificateEditor.vue:177
-#: src/views/certificate/CertificateEditor.vue:192
+#: src/views/certificate/components/CertificateEditor.vue:165
+#: src/views/certificate/components/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:194
 msgid "This field is required"
 msgstr ""
 
@@ -3428,6 +3471,10 @@ msgstr ""
 msgid "This field should only contain letters, unicode characters, numbers, and -_."
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:103
+msgid "This operation will only remove the certificate from the database. The certificate files on the file system will not be deleted."
+msgstr ""
+
 #: src/views/system/Backup/BackupCreator.vue:141
 msgid "This token will only be shown once and cannot be retrieved later. Please make sure to save it in a secure location."
 msgstr ""
@@ -3464,6 +3511,10 @@ msgstr ""
 msgid "Title"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:121
+msgid "To confirm revocation, please type \"Revoke\" in the field below:"
+msgstr ""
+
 #: src/views/preference/components/TOTP.vue:68
 msgid "To enable it, you need to install the Google or Microsoft Authenticator app on your mobile phone."
 msgstr ""
@@ -3528,7 +3579,7 @@ msgstr ""
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:75
-#: src/views/site/site_list/columns.tsx:110
+#: src/views/site/site_list/columns.tsx:82
 #: src/views/stream/components/RightSettings.vue:99
 #: src/views/stream/StreamList.vue:67
 #: src/views/user/userColumns.tsx:54
@@ -3672,6 +3723,10 @@ msgstr ""
 msgid "WebAuthn settings are not configured"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:54
+msgid "WebSocket connection error"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:83
 msgid "When Enabled, Nginx UI will automatically re-register users upon startup. Generally, do not enable this unless you are in a dev environment and using Pebble as CA."
 msgstr ""

+ 114 - 44
app/src/language/ru_RU/app.po

@@ -38,7 +38,7 @@ msgid "Access Logs"
 msgstr "Журналы доступа"
 
 #: src/routes/modules/certificates.ts:20 src/views/certificate/ACMEUser.vue:113
-#: src/views/certificate/ACMEUserSelector.vue:85
+#: src/views/certificate/components/ACMEUserSelector.vue:85
 msgid "ACME User"
 msgstr "Пользователь ACME"
 
@@ -52,7 +52,7 @@ msgstr "Пользователь ACME"
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
 #: src/views/preference/components/ExternalNotify/columns.ts:46
-#: src/views/site/site_list/columns.tsx:117 src/views/stream/StreamList.vue:74
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/StreamList.vue:74
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Действие"
@@ -280,7 +280,7 @@ msgstr ""
 msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:255
+#: src/views/certificate/components/CertificateEditor.vue:257
 #: src/views/config/ConfigEditor.vue:262 src/views/config/ConfigList.vue:112
 #: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:285
@@ -461,6 +461,12 @@ msgstr "Ошибка анализа сертификата"
 msgid "Certificate path is empty"
 msgstr "Шаблоны конфигурации"
 
+#: src/views/certificate/components/RemoveCert.vue:41
+#: src/views/certificate/components/RemoveCert.vue:61
+#, fuzzy
+msgid "Certificate removed successfully"
+msgstr "Сертификат успешно продлен"
+
 #: src/views/preference/CertSettings.vue:27
 msgid "Certificate Renewal Interval"
 msgstr "Интервал обновления сертификата"
@@ -469,7 +475,7 @@ msgstr "Интервал обновления сертификата"
 msgid "Certificate renewed successfully"
 msgstr "Сертификат успешно продлен"
 
-#: src/views/certificate/CertificateEditor.vue:128
+#: src/views/certificate/components/CertificateEditor.vue:128
 #: src/views/site/cert/Cert.vue:60
 msgid "Certificate Status"
 msgid_plural "Certificates Status"
@@ -477,7 +483,7 @@ msgstr[0] "Статус сертификата"
 msgstr[1] "Статус сертификатов"
 
 #: src/routes/modules/certificates.ts:11
-#: src/views/certificate/CertificateList/Certificate.vue:13
+#: src/views/certificate/CertificateList/Certificate.vue:14
 msgid "Certificates"
 msgstr "Сертификаты"
 
@@ -774,6 +780,7 @@ msgstr "Ошибка расшифровки"
 
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:21
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
+#: src/views/certificate/components/RemoveCert.vue:87
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
 #: src/views/site/site_list/SiteList.vue:176
@@ -781,6 +788,11 @@ msgstr "Ошибка расшифровки"
 msgid "Delete"
 msgstr "Удалить"
 
+#: src/views/certificate/components/RemoveCert.vue:92
+#, fuzzy
+msgid "Delete Certificate"
+msgstr "Обновить сертификат"
+
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:35
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:547
 msgid "Delete Permanently"
@@ -965,7 +977,7 @@ msgstr "Включение %{conf_name} in %{node_name} успешно"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:159
 #: src/views/site/site_edit/SiteEdit.vue:199
-#: src/views/site/site_list/columns.tsx:102 src/views/stream/StreamEdit.vue:182
+#: src/views/site/site_list/columns.tsx:111 src/views/stream/StreamEdit.vue:182
 #: src/views/stream/StreamList.vue:58 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Отключено"
@@ -1036,11 +1048,11 @@ msgid_plural "Documents"
 msgstr[0] "API Документ"
 msgstr[1] "API Документ"
 
-#: src/views/certificate/WildcardCertificate.vue:68
+#: src/views/certificate/components/WildcardCertificate.vue:68
 msgid "Domain"
 msgstr "Домен"
 
-#: src/views/certificate/CertificateEditor.vue:112
+#: src/views/certificate/components/CertificateEditor.vue:112
 msgid "Domains list is empty, try to reopen Auto Cert for %{config}"
 msgstr ""
 "Список доменов пуст, попробуйте заново создать авто-сертификат для %{config}"
@@ -1210,7 +1222,7 @@ msgstr "Включить TOTP"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:155
 #: src/views/site/site_edit/SiteEdit.vue:193
-#: src/views/site/site_list/columns.tsx:101
+#: src/views/site/site_list/columns.tsx:110
 #: src/views/stream/components/RightSettings.vue:81
 #: src/views/stream/StreamEdit.vue:176 src/views/stream/StreamList.vue:54
 #: src/views/user/userColumns.tsx:38
@@ -1420,6 +1432,11 @@ msgstr ""
 msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:66
+#, fuzzy
+msgid "Failed to delete certificate"
+msgstr "Не удалось получить сертификат"
+
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:63
 #: src/views/stream/components/RightSettings.vue:45
 #: src/views/stream/StreamList.vue:100
@@ -1538,6 +1555,11 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:48
+#, fuzzy
+msgid "Failed to revoke certificate"
+msgstr "Не удалось получить сертификат"
+
 #: src/views/site/site_edit/SiteEdit.vue:139
 #: src/views/stream/StreamEdit.vue:122
 msgid "Failed to save, syntax error(s) was detected in the configuration."
@@ -1723,6 +1745,15 @@ msgstr ""
 "количества попыток в течение пороговых минут блокировки, IP будет "
 "заблокирован на определенный период времени."
 
+#: src/views/site/cert/components/AutoCertStepOne.vue:117
+#, fuzzy
+msgid ""
+"If you want to automatically revoke the old certificate, please enable this "
+"option."
+msgstr ""
+"Если у вашего домена есть записи CNAME и вы не можете получить сертификаты, "
+"вам нужно включить эту опцию."
+
 #: src/views/preference/components/AddPasskey.vue:70
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr ""
@@ -1736,12 +1767,12 @@ msgstr ""
 "Если у вашего домена есть записи CNAME и вы не можете получить сертификаты, "
 "вам нужно включить эту опцию."
 
-#: src/views/certificate/CertificateList/Certificate.vue:20
+#: src/views/certificate/CertificateList/Certificate.vue:22
 msgid "Import"
 msgstr "Импорт"
 
 #: src/routes/modules/certificates.ts:46
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Import Certificate"
 msgstr "Импортировать сертификат"
 
@@ -1867,11 +1898,11 @@ msgstr "Неверный код восстановления"
 msgid "IP"
 msgstr "IP"
 
-#: src/views/certificate/CertificateList/Certificate.vue:28
+#: src/views/certificate/CertificateList/Certificate.vue:31
 msgid "Issue wildcard certificate"
 msgstr "Выпустить wildcard-сертификат"
 
-#: src/views/certificate/WildcardCertificate.vue:59
+#: src/views/certificate/components/WildcardCertificate.vue:59
 msgid "Issue Wildcard Certificate"
 msgstr "Выпустить Wildcard сертификат"
 
@@ -1937,8 +1968,8 @@ msgstr "Оставьте пустым без изменений"
 msgid "Leave blank if you don't need this."
 msgstr "Оставьте пустым без изменений."
 
-#: src/views/certificate/CertificateEditor.vue:220
-#: src/views/certificate/CertificateEditor.vue:233
+#: src/views/certificate/components/CertificateEditor.vue:222
+#: src/views/certificate/components/CertificateEditor.vue:235
 msgid "Leave blank will not change anything"
 msgstr "Если оставить пустым, ничего не изменится"
 
@@ -1988,7 +2019,7 @@ msgstr "Локация"
 msgid "Locations"
 msgstr "Локации"
 
-#: src/views/certificate/CertificateEditor.vue:243
+#: src/views/certificate/components/CertificateEditor.vue:245
 msgid "Log"
 msgstr "Журнал"
 
@@ -2030,7 +2061,7 @@ msgstr ""
 "выполнять команду logrotate с интервалом, который вы установите в минутах."
 
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:163
-#: src/views/site/site_list/columns.tsx:103
+#: src/views/site/site_list/columns.tsx:112
 msgid "Maintenance"
 msgstr ""
 
@@ -2106,7 +2137,7 @@ msgid "Modify"
 msgstr "Изменить"
 
 #: src/routes/modules/certificates.ts:36
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Modify Certificate"
 msgstr "Изменить сертификат"
 
@@ -2123,8 +2154,8 @@ msgid "Multi-line Directive"
 msgstr "Многострочная директива"
 
 #: src/views/certificate/ACMEUser.vue:13
-#: src/views/certificate/CertificateEditor.vue:160
 #: src/views/certificate/CertificateList/certColumns.tsx:10
+#: src/views/certificate/components/CertificateEditor.vue:162
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:305
@@ -2175,7 +2206,7 @@ msgstr "Новый путь"
 msgid "New version released"
 msgstr "Вышла новая версия"
 
-#: src/views/certificate/WildcardCertificate.vue:91
+#: src/views/certificate/components/WildcardCertificate.vue:91
 #: src/views/site/cert/components/ObtainCert.vue:211
 #: src/views/site/site_add/SiteAdd.vue:141
 msgid "Next"
@@ -2344,7 +2375,7 @@ msgid "Node"
 msgstr "Имя узла"
 
 #: src/views/site/site_edit/RightSettings.vue:66
-#: src/views/site/site_list/columns.tsx:63
+#: src/views/site/site_list/columns.tsx:65
 #: src/views/stream/components/RightSettings.vue:90
 #: src/views/stream/StreamList.vue:30
 #, fuzzy
@@ -2703,6 +2734,10 @@ msgstr "Пожалуйста, выберите хотя бы один узел"
 msgid "Please select at least one node to upgrade"
 msgstr "Пожалуйста, выберите хотя бы один узел"
 
+#: src/views/certificate/components/RemoveCert.vue:27
+msgid "Please type \"Revoke\" to confirm"
+msgstr ""
+
 #: src/views/preference/ServerSettings.vue:21
 #, fuzzy
 msgid "Port"
@@ -2980,8 +3015,8 @@ msgstr "Переименовано успешно"
 msgid "Renamed successfully"
 msgstr "Переименовано успешно"
 
-#: src/views/certificate/RenewCert.vue:45
-#: src/views/certificate/RenewCert.vue:49
+#: src/views/certificate/components/RenewCert.vue:45
+#: src/views/certificate/components/RenewCert.vue:49
 msgid "Renew Certificate"
 msgstr "Обновить сертификат"
 
@@ -2993,8 +3028,8 @@ msgstr "Ошибка обновления сертификата"
 msgid "Renew Certificate Success"
 msgstr "Успешное обновление сертификата"
 
-#: src/views/certificate/RenewCert.vue:27
-#: src/views/certificate/WildcardCertificate.vue:48
+#: src/views/certificate/components/RenewCert.vue:27
+#: src/views/certificate/components/WildcardCertificate.vue:48
 msgid "Renew successfully"
 msgstr "Успешно обновлено"
 
@@ -3080,6 +3115,27 @@ msgstr "Ошибка разбора конфигурации Nginx"
 msgid "Restore this version"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:26
+#: src/views/certificate/components/RemoveCert.vue:95
+msgid "Revoke"
+msgstr ""
+
+#: src/views/site/cert/components/AutoCertStepOne.vue:114
+#, fuzzy
+msgid "Revoke Old Certificate"
+msgstr "Обновить сертификат"
+
+#: src/views/certificate/components/RemoveCert.vue:109
+#, fuzzy
+msgid "Revoke this certificate"
+msgstr "Обновить сертификат"
+
+#: src/views/certificate/components/RemoveCert.vue:117
+msgid ""
+"Revoking a certificate will affect any services currently using it. This "
+"action cannot be undone."
+msgstr ""
+
 #: src/views/preference/AuthSettings.vue:107
 msgid "RP Display Name"
 msgstr ""
@@ -3103,7 +3159,7 @@ msgstr "Выполняется"
 #: src/components/ChatGPT/ChatGPT.vue:355
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:64
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
-#: src/views/certificate/CertificateEditor.vue:262
+#: src/views/certificate/components/CertificateEditor.vue:264
 #: src/views/config/components/ConfigName.vue:59
 #: src/views/config/ConfigEditor.vue:271
 #: src/views/preference/components/Passkey.vue:130
@@ -3167,7 +3223,7 @@ msgstr "Поток %{name} успешно сохранён на %{node}"
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
-#: src/views/certificate/CertificateEditor.vue:49
+#: src/views/certificate/components/CertificateEditor.vue:49
 #: src/views/preference/Preference.vue:124
 msgid "Save successfully"
 msgstr "Сохранено успешно"
@@ -3337,7 +3393,7 @@ msgstr ""
 msgid "Skip Installation"
 msgstr "Установить"
 
-#: src/views/certificate/CertificateEditor.vue:211
+#: src/views/certificate/components/CertificateEditor.vue:213
 msgid "SSL Certificate Content"
 msgstr "Содержимое SSL-сертификата"
 
@@ -3350,15 +3406,15 @@ msgstr ""
 msgid "SSL certificate file not found"
 msgstr "Содержимое ключа SSL-сертификата"
 
-#: src/views/certificate/CertificateEditor.vue:224
+#: src/views/certificate/components/CertificateEditor.vue:226
 msgid "SSL Certificate Key Content"
 msgstr "Содержимое ключа SSL-сертификата"
 
-#: src/views/certificate/CertificateEditor.vue:190
+#: src/views/certificate/components/CertificateEditor.vue:192
 msgid "SSL Certificate Key Path"
 msgstr "Путь к ключу SSL-сертификата"
 
-#: src/views/certificate/CertificateEditor.vue:175
+#: src/views/certificate/components/CertificateEditor.vue:177
 #: src/views/preference/ServerSettings.vue:36
 msgid "SSL Certificate Path"
 msgstr "Путь к SSL сертификату"
@@ -3404,7 +3460,7 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/site/site_list/columns.tsx:80 src/views/stream/StreamList.vue:47
+#: src/views/site/site_list/columns.tsx:89 src/views/stream/StreamList.vue:47
 msgid "Status"
 msgstr "Статус"
 
@@ -3528,7 +3584,7 @@ msgstr "Синхронизировать с"
 msgid "Sync strategy"
 msgstr "Синхронизировать сертификат"
 
-#: src/views/certificate/CertificateEditor.vue:204
+#: src/views/certificate/components/CertificateEditor.vue:206
 msgid "Sync to"
 msgstr "Синхронизировать с"
 
@@ -3546,7 +3602,7 @@ msgstr "Система"
 msgid "System Backup"
 msgstr "Система"
 
-#: src/views/certificate/ACMEUserSelector.vue:88
+#: src/views/certificate/components/ACMEUserSelector.vue:88
 msgid "System Initial User"
 msgstr "Первоначальный пользователь системы"
 
@@ -3601,11 +3657,11 @@ msgstr ""
 "Имя модели должно содержать только буквы, юникод, цифры, дефисы, тире и "
 "точки."
 
-#: src/views/certificate/CertificateEditor.vue:214
+#: src/views/certificate/components/CertificateEditor.vue:216
 msgid "The input is not a SSL Certificate"
 msgstr "Входные данные не являются SSL-сертификатом"
 
-#: src/views/certificate/CertificateEditor.vue:227
+#: src/views/certificate/components/CertificateEditor.vue:229
 msgid "The input is not a SSL Certificate Key"
 msgstr "Введенные данные не являются ключом SSL сертификата"
 
@@ -3637,11 +3693,11 @@ msgstr ""
 msgid "The parameter of server_name is required"
 msgstr "server_name параметр обязателен"
 
-#: src/views/certificate/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:181
 msgid "The path exists, but the file is not a certificate"
 msgstr "Путь существует, но файл не является сертификатом"
 
-#: src/views/certificate/CertificateEditor.vue:194
+#: src/views/certificate/components/CertificateEditor.vue:196
 msgid "The path exists, but the file is not a private key"
 msgstr "Путь существует, но файл не является приватным ключом"
 
@@ -3693,17 +3749,17 @@ msgid ""
 "lose access to your account."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:102
+#: src/views/certificate/components/CertificateEditor.vue:102
 msgid "This Auto Cert item is invalid, please remove it."
 msgstr "Этот элемент автосертификата недействителен, удалите его.."
 
-#: src/views/certificate/CertificateEditor.vue:92
+#: src/views/certificate/components/CertificateEditor.vue:92
 msgid "This certificate is managed by Nginx UI"
 msgstr "Этот сертификат под управлением Nginx UI"
 
-#: src/views/certificate/CertificateEditor.vue:163
-#: src/views/certificate/CertificateEditor.vue:177
-#: src/views/certificate/CertificateEditor.vue:192
+#: src/views/certificate/components/CertificateEditor.vue:165
+#: src/views/certificate/components/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:194
 msgid "This field is required"
 msgstr "Это поле обязательно для заполнения"
 
@@ -3730,6 +3786,12 @@ msgstr ""
 "Имя модели должно содержать только буквы, юникод, цифры, дефисы, тире и "
 "точки."
 
+#: src/views/certificate/components/RemoveCert.vue:103
+msgid ""
+"This operation will only remove the certificate from the database. The "
+"certificate files on the file system will not be deleted."
+msgstr ""
+
 #: src/views/system/Backup/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -3775,6 +3837,10 @@ msgstr "Советы"
 msgid "Title"
 msgstr "Заголовок"
 
+#: src/views/certificate/components/RemoveCert.vue:121
+msgid "To confirm revocation, please type \"Revoke\" in the field below:"
+msgstr ""
+
 #: src/views/preference/components/TOTP.vue:68
 msgid ""
 "To enable it, you need to install the Google or Microsoft Authenticator app "
@@ -3861,7 +3927,7 @@ msgstr "Успешно обновлено"
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:75
-#: src/views/site/site_list/columns.tsx:110
+#: src/views/site/site_list/columns.tsx:82
 #: src/views/stream/components/RightSettings.vue:99
 #: src/views/stream/StreamList.vue:67 src/views/user/userColumns.tsx:54
 msgid "Updated at"
@@ -4016,6 +4082,10 @@ msgstr ""
 msgid "WebAuthn settings are not configured"
 msgstr "Настройки WebAuthn не настроены"
 
+#: src/views/certificate/components/RemoveCert.vue:54
+msgid "WebSocket connection error"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:83
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "

+ 114 - 44
app/src/language/tr_TR/app.po

@@ -35,7 +35,7 @@ msgid "Access Logs"
 msgstr "Erişim Günlükleri"
 
 #: src/routes/modules/certificates.ts:20 src/views/certificate/ACMEUser.vue:113
-#: src/views/certificate/ACMEUserSelector.vue:85
+#: src/views/certificate/components/ACMEUserSelector.vue:85
 msgid "ACME User"
 msgstr "ACME Kullanıcısı"
 
@@ -49,7 +49,7 @@ msgstr "ACME Kullanıcısı"
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
 #: src/views/preference/components/ExternalNotify/columns.ts:46
-#: src/views/site/site_list/columns.tsx:117 src/views/stream/StreamList.vue:74
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/StreamList.vue:74
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Eylem"
@@ -277,7 +277,7 @@ msgstr ""
 msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:255
+#: src/views/certificate/components/CertificateEditor.vue:257
 #: src/views/config/ConfigEditor.vue:262 src/views/config/ConfigList.vue:112
 #: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:285
@@ -461,6 +461,12 @@ msgstr "Senkronizasyon Sertifikası Hatası"
 msgid "Certificate path is empty"
 msgstr "Yapılandırma Şablonları"
 
+#: src/views/certificate/components/RemoveCert.vue:41
+#: src/views/certificate/components/RemoveCert.vue:61
+#, fuzzy
+msgid "Certificate removed successfully"
+msgstr "Başarıyla temizlendi"
+
 #: src/views/preference/CertSettings.vue:27
 msgid "Certificate Renewal Interval"
 msgstr "Sertifika Yenileme Aralığı"
@@ -470,7 +476,7 @@ msgstr "Sertifika Yenileme Aralığı"
 msgid "Certificate renewed successfully"
 msgstr "Başarıyla temizlendi"
 
-#: src/views/certificate/CertificateEditor.vue:128
+#: src/views/certificate/components/CertificateEditor.vue:128
 #: src/views/site/cert/Cert.vue:60
 msgid "Certificate Status"
 msgid_plural "Certificates Status"
@@ -478,7 +484,7 @@ msgstr[0] "Sertifika Durumu"
 msgstr[1] "Sertifikaların Durumu"
 
 #: src/routes/modules/certificates.ts:11
-#: src/views/certificate/CertificateList/Certificate.vue:13
+#: src/views/certificate/CertificateList/Certificate.vue:14
 msgid "Certificates"
 msgstr "Sertifikalar"
 
@@ -777,6 +783,7 @@ msgstr "Açıklama"
 
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:21
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
+#: src/views/certificate/components/RemoveCert.vue:87
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
 #: src/views/site/site_list/SiteList.vue:176
@@ -784,6 +791,11 @@ msgstr "Açıklama"
 msgid "Delete"
 msgstr "Sil"
 
+#: src/views/certificate/components/RemoveCert.vue:92
+#, fuzzy
+msgid "Delete Certificate"
+msgstr "Sertifika Yenileme"
+
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:35
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:547
 msgid "Delete Permanently"
@@ -984,7 +996,7 @@ msgstr ""
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:159
 #: src/views/site/site_edit/SiteEdit.vue:199
-#: src/views/site/site_list/columns.tsx:102 src/views/stream/StreamEdit.vue:182
+#: src/views/site/site_list/columns.tsx:111 src/views/stream/StreamEdit.vue:182
 #: src/views/stream/StreamList.vue:58 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Devre dışı"
@@ -1054,11 +1066,11 @@ msgid_plural "Documents"
 msgstr[0] "API Dökümanı"
 msgstr[1] "API Dökümanı"
 
-#: src/views/certificate/WildcardCertificate.vue:68
+#: src/views/certificate/components/WildcardCertificate.vue:68
 msgid "Domain"
 msgstr "Alan Adı"
 
-#: src/views/certificate/CertificateEditor.vue:112
+#: src/views/certificate/components/CertificateEditor.vue:112
 msgid "Domains list is empty, try to reopen Auto Cert for %{config}"
 msgstr ""
 "Alan adları listesi boş, %{config} için Otomatik Sertifikayı yeniden açmayı "
@@ -1243,7 +1255,7 @@ msgstr "TOTP'yi Etkinleştir"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:155
 #: src/views/site/site_edit/SiteEdit.vue:193
-#: src/views/site/site_list/columns.tsx:101
+#: src/views/site/site_list/columns.tsx:110
 #: src/views/stream/components/RightSettings.vue:81
 #: src/views/stream/StreamEdit.vue:176 src/views/stream/StreamList.vue:54
 #: src/views/user/userColumns.tsx:38
@@ -1453,6 +1465,11 @@ msgstr ""
 msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:66
+#, fuzzy
+msgid "Failed to delete certificate"
+msgstr "Sertifika alınamadı"
+
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:63
 #: src/views/stream/components/RightSettings.vue:45
 #: src/views/stream/StreamList.vue:100
@@ -1571,6 +1588,11 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:48
+#, fuzzy
+msgid "Failed to revoke certificate"
+msgstr "Sertifika alınamadı"
+
 #: src/views/site/site_edit/SiteEdit.vue:139
 #: src/views/stream/StreamEdit.vue:122
 msgid "Failed to save, syntax error(s) was detected in the configuration."
@@ -1756,6 +1778,15 @@ msgstr ""
 "yasaklama eşiği dakikaları içinde maksimum deneme sayısına ulaşırsa, IP "
 "adresi belirli bir süre için yasaklanacaktır."
 
+#: src/views/site/cert/components/AutoCertStepOne.vue:117
+#, fuzzy
+msgid ""
+"If you want to automatically revoke the old certificate, please enable this "
+"option."
+msgstr ""
+"Alan adınızda CNAME kayıtları varsa ve sertifika alamıyorsanız, bu seçeneği "
+"etkinleştirmeniz gerekir."
+
 #: src/views/preference/components/AddPasskey.vue:70
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr ""
@@ -1770,12 +1801,12 @@ msgstr ""
 "Alan adınızda CNAME kayıtları varsa ve sertifika alamıyorsanız, bu seçeneği "
 "etkinleştirmeniz gerekir."
 
-#: src/views/certificate/CertificateList/Certificate.vue:20
+#: src/views/certificate/CertificateList/Certificate.vue:22
 msgid "Import"
 msgstr "İçe Aktar"
 
 #: src/routes/modules/certificates.ts:46
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Import Certificate"
 msgstr "Sertifika İçe Aktar"
 
@@ -1903,11 +1934,11 @@ msgstr "Geçersiz 2FA veya kurtarma kodu"
 msgid "IP"
 msgstr "IP"
 
-#: src/views/certificate/CertificateList/Certificate.vue:28
+#: src/views/certificate/CertificateList/Certificate.vue:31
 msgid "Issue wildcard certificate"
 msgstr "Wildcard sertifikası düzenle"
 
-#: src/views/certificate/WildcardCertificate.vue:59
+#: src/views/certificate/components/WildcardCertificate.vue:59
 msgid "Issue Wildcard Certificate"
 msgstr "Wildcard Sertifikası Yayınlama"
 
@@ -1972,8 +2003,8 @@ msgstr "Buna ihtiyacınız yoksa boş bırakın."
 msgid "Leave blank if you don't need this."
 msgstr "Buna ihtiyacınız yoksa boş bırakın."
 
-#: src/views/certificate/CertificateEditor.vue:220
-#: src/views/certificate/CertificateEditor.vue:233
+#: src/views/certificate/components/CertificateEditor.vue:222
+#: src/views/certificate/components/CertificateEditor.vue:235
 msgid "Leave blank will not change anything"
 msgstr "Boş bırakmak hiçbir şeyi değiştirmeyecektir"
 
@@ -2023,7 +2054,7 @@ msgstr "Konum"
 msgid "Locations"
 msgstr "Konumlar"
 
-#: src/views/certificate/CertificateEditor.vue:243
+#: src/views/certificate/components/CertificateEditor.vue:245
 msgid "Log"
 msgstr "Günlük"
 
@@ -2065,7 +2096,7 @@ msgstr ""
 "dakika aralığında logrotate komutunu çalıştıracaktır."
 
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:163
-#: src/views/site/site_list/columns.tsx:103
+#: src/views/site/site_list/columns.tsx:112
 msgid "Maintenance"
 msgstr ""
 
@@ -2153,7 +2184,7 @@ msgid "Modify"
 msgstr "Değiştir"
 
 #: src/routes/modules/certificates.ts:36
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 #, fuzzy
 msgid "Modify Certificate"
 msgstr "Sertifika Değiştirme"
@@ -2174,8 +2205,8 @@ msgid "Multi-line Directive"
 msgstr "Çok Hatlı Direktif"
 
 #: src/views/certificate/ACMEUser.vue:13
-#: src/views/certificate/CertificateEditor.vue:160
 #: src/views/certificate/CertificateList/certColumns.tsx:10
+#: src/views/certificate/components/CertificateEditor.vue:162
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:305
@@ -2234,7 +2265,7 @@ msgstr "Yeni Yol"
 msgid "New version released"
 msgstr "Yeni sürüm yayınlandı"
 
-#: src/views/certificate/WildcardCertificate.vue:91
+#: src/views/certificate/components/WildcardCertificate.vue:91
 #: src/views/site/cert/components/ObtainCert.vue:211
 #: src/views/site/site_add/SiteAdd.vue:141
 #, fuzzy
@@ -2414,7 +2445,7 @@ msgid "Node"
 msgstr "Yeni Ad"
 
 #: src/views/site/site_edit/RightSettings.vue:66
-#: src/views/site/site_list/columns.tsx:63
+#: src/views/site/site_list/columns.tsx:65
 #: src/views/stream/components/RightSettings.vue:90
 #: src/views/stream/StreamList.vue:30
 #, fuzzy
@@ -2821,6 +2852,10 @@ msgstr "Lütfen yükseltmek için en az bir düğüm seçin"
 msgid "Please select at least one node to upgrade"
 msgstr "Lütfen yükseltmek için en az bir düğüm seçin"
 
+#: src/views/certificate/components/RemoveCert.vue:27
+msgid "Please type \"Revoke\" to confirm"
+msgstr ""
+
 #: src/views/preference/ServerSettings.vue:21
 #, fuzzy
 msgid "Port"
@@ -3140,8 +3175,8 @@ msgstr "Yeniden adlandırma başarıyla"
 msgid "Renamed successfully"
 msgstr "Yeniden adlandırma başarıyla"
 
-#: src/views/certificate/RenewCert.vue:45
-#: src/views/certificate/RenewCert.vue:49
+#: src/views/certificate/components/RenewCert.vue:45
+#: src/views/certificate/components/RenewCert.vue:49
 #, fuzzy
 msgid "Renew Certificate"
 msgstr "Sertifika Yenileme"
@@ -3156,8 +3191,8 @@ msgstr "Sertifika Yenileme Hatası"
 msgid "Renew Certificate Success"
 msgstr "Sertifika Yenileme Başarısı"
 
-#: src/views/certificate/RenewCert.vue:27
-#: src/views/certificate/WildcardCertificate.vue:48
+#: src/views/certificate/components/RenewCert.vue:27
+#: src/views/certificate/components/WildcardCertificate.vue:48
 #, fuzzy
 msgid "Renew successfully"
 msgstr "Başarıyla yenileyin"
@@ -3251,6 +3286,27 @@ msgstr "Nginx Yapılandırma Ayrıştırma Hatası"
 msgid "Restore this version"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:26
+#: src/views/certificate/components/RemoveCert.vue:95
+msgid "Revoke"
+msgstr ""
+
+#: src/views/site/cert/components/AutoCertStepOne.vue:114
+#, fuzzy
+msgid "Revoke Old Certificate"
+msgstr "Sertifika Yenileme"
+
+#: src/views/certificate/components/RemoveCert.vue:109
+#, fuzzy
+msgid "Revoke this certificate"
+msgstr "Sertifika Yenileme"
+
+#: src/views/certificate/components/RemoveCert.vue:117
+msgid ""
+"Revoking a certificate will affect any services currently using it. This "
+"action cannot be undone."
+msgstr ""
+
 #: src/views/preference/AuthSettings.vue:107
 msgid "RP Display Name"
 msgstr ""
@@ -3276,7 +3332,7 @@ msgstr "Çalışıyor"
 #: src/components/ChatGPT/ChatGPT.vue:355
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:64
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
-#: src/views/certificate/CertificateEditor.vue:262
+#: src/views/certificate/components/CertificateEditor.vue:264
 #: src/views/config/components/ConfigName.vue:59
 #: src/views/config/ConfigEditor.vue:271
 #: src/views/preference/components/Passkey.vue:130
@@ -3346,7 +3402,7 @@ msgstr "%{conf_name} başarıyla %{node_name} düğümüne kopyalandı"
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
-#: src/views/certificate/CertificateEditor.vue:49
+#: src/views/certificate/components/CertificateEditor.vue:49
 #: src/views/preference/Preference.vue:124
 #, fuzzy
 msgid "Save successfully"
@@ -3533,7 +3589,7 @@ msgstr ""
 msgid "Skip Installation"
 msgstr "Yükle"
 
-#: src/views/certificate/CertificateEditor.vue:211
+#: src/views/certificate/components/CertificateEditor.vue:213
 #, fuzzy
 msgid "SSL Certificate Content"
 msgstr "SSL Sertifika İçeriği"
@@ -3547,17 +3603,17 @@ msgstr ""
 msgid "SSL certificate file not found"
 msgstr "SSL Sertifika Anahtarı İçeriği"
 
-#: src/views/certificate/CertificateEditor.vue:224
+#: src/views/certificate/components/CertificateEditor.vue:226
 #, fuzzy
 msgid "SSL Certificate Key Content"
 msgstr "SSL Sertifika Anahtarı İçeriği"
 
-#: src/views/certificate/CertificateEditor.vue:190
+#: src/views/certificate/components/CertificateEditor.vue:192
 #, fuzzy
 msgid "SSL Certificate Key Path"
 msgstr "SSL Sertifikası Anahtar Yolu"
 
-#: src/views/certificate/CertificateEditor.vue:175
+#: src/views/certificate/components/CertificateEditor.vue:177
 #: src/views/preference/ServerSettings.vue:36
 #, fuzzy
 msgid "SSL Certificate Path"
@@ -3606,7 +3662,7 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/site/site_list/columns.tsx:80 src/views/stream/StreamList.vue:47
+#: src/views/site/site_list/columns.tsx:89 src/views/stream/StreamList.vue:47
 #, fuzzy
 msgid "Status"
 msgstr "Durum"
@@ -3744,7 +3800,7 @@ msgstr "Şununla senkronize et"
 msgid "Sync strategy"
 msgstr "Senkronizasyon Sertifikası"
 
-#: src/views/certificate/CertificateEditor.vue:204
+#: src/views/certificate/components/CertificateEditor.vue:206
 #, fuzzy
 msgid "Sync to"
 msgstr "Şununla senkronize et"
@@ -3764,7 +3820,7 @@ msgstr "Sistem"
 msgid "System Backup"
 msgstr "Sistem"
 
-#: src/views/certificate/ACMEUserSelector.vue:88
+#: src/views/certificate/components/ACMEUserSelector.vue:88
 #, fuzzy
 msgid "System Initial User"
 msgstr "Sistem İlk Kullanıcısı"
@@ -3823,12 +3879,12 @@ msgid ""
 msgstr ""
 "Model adı yalnızca harf, unicode, sayı, tire, çizgi ve nokta içermelidir."
 
-#: src/views/certificate/CertificateEditor.vue:214
+#: src/views/certificate/components/CertificateEditor.vue:216
 #, fuzzy
 msgid "The input is not a SSL Certificate"
 msgstr "Giriş bir SSL Sertifikası değil"
 
-#: src/views/certificate/CertificateEditor.vue:227
+#: src/views/certificate/components/CertificateEditor.vue:229
 #, fuzzy
 msgid "The input is not a SSL Certificate Key"
 msgstr "Girdi bir SSL Sertifika Anahtarı değil"
@@ -3859,12 +3915,12 @@ msgstr ""
 msgid "The parameter of server_name is required"
 msgstr "server_name parametresi gereklidir"
 
-#: src/views/certificate/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:181
 #, fuzzy
 msgid "The path exists, but the file is not a certificate"
 msgstr "Yol var, ancak dosya bir sertifika değil"
 
-#: src/views/certificate/CertificateEditor.vue:194
+#: src/views/certificate/components/CertificateEditor.vue:196
 #, fuzzy
 msgid "The path exists, but the file is not a private key"
 msgstr "Yol var, ancak dosya bir özel anahtar değil"
@@ -3922,19 +3978,19 @@ msgid ""
 "lose access to your account."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:102
+#: src/views/certificate/components/CertificateEditor.vue:102
 #, fuzzy
 msgid "This Auto Cert item is invalid, please remove it."
 msgstr "Bu Otomatik Sertifika öğesi geçersizdir, lütfen kaldırın."
 
-#: src/views/certificate/CertificateEditor.vue:92
+#: src/views/certificate/components/CertificateEditor.vue:92
 #, fuzzy
 msgid "This certificate is managed by Nginx UI"
 msgstr "Bu sertifika Nginx UI tarafından yönetilir"
 
-#: src/views/certificate/CertificateEditor.vue:163
-#: src/views/certificate/CertificateEditor.vue:177
-#: src/views/certificate/CertificateEditor.vue:192
+#: src/views/certificate/components/CertificateEditor.vue:165
+#: src/views/certificate/components/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:194
 #, fuzzy
 msgid "This field is required"
 msgstr "Bu alan gereklidir"
@@ -3962,6 +4018,12 @@ msgid ""
 msgstr ""
 "Model adı yalnızca harf, unicode, sayı, tire, çizgi ve nokta içermelidir."
 
+#: src/views/certificate/components/RemoveCert.vue:103
+msgid ""
+"This operation will only remove the certificate from the database. The "
+"certificate files on the file system will not be deleted."
+msgstr ""
+
 #: src/views/system/Backup/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -4010,6 +4072,10 @@ msgstr "İpuçları"
 msgid "Title"
 msgstr "Başlık"
 
+#: src/views/certificate/components/RemoveCert.vue:121
+msgid "To confirm revocation, please type \"Revoke\" in the field below:"
+msgstr ""
+
 #: src/views/preference/components/TOTP.vue:68
 #, fuzzy
 msgid ""
@@ -4112,7 +4178,7 @@ msgstr "Güncellendi"
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:75
-#: src/views/site/site_list/columns.tsx:110
+#: src/views/site/site_list/columns.tsx:82
 #: src/views/stream/components/RightSettings.vue:99
 #: src/views/stream/StreamList.vue:67 src/views/user/userColumns.tsx:54
 #, fuzzy
@@ -4289,6 +4355,10 @@ msgstr ""
 msgid "WebAuthn settings are not configured"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:54
+msgid "WebSocket connection error"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:83
 #, fuzzy
 msgid ""

+ 111 - 44
app/src/language/vi_VN/app.po

@@ -31,7 +31,7 @@ msgid "Access Logs"
 msgstr "Log truy cập"
 
 #: src/routes/modules/certificates.ts:20 src/views/certificate/ACMEUser.vue:113
-#: src/views/certificate/ACMEUserSelector.vue:85
+#: src/views/certificate/components/ACMEUserSelector.vue:85
 #, fuzzy
 msgid "ACME User"
 msgstr "Người dùng"
@@ -46,7 +46,7 @@ msgstr "Người dùng"
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
 #: src/views/preference/components/ExternalNotify/columns.ts:46
-#: src/views/site/site_list/columns.tsx:117 src/views/stream/StreamList.vue:74
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/StreamList.vue:74
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Hành động"
@@ -292,7 +292,7 @@ msgstr ""
 msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:255
+#: src/views/certificate/components/CertificateEditor.vue:257
 #: src/views/config/ConfigEditor.vue:262 src/views/config/ConfigList.vue:112
 #: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:285
@@ -480,6 +480,12 @@ msgstr "Chứng chỉ đã hết hạn"
 msgid "Certificate path is empty"
 msgstr "Mẫu Cấu hình"
 
+#: src/views/certificate/components/RemoveCert.vue:41
+#: src/views/certificate/components/RemoveCert.vue:61
+#, fuzzy
+msgid "Certificate removed successfully"
+msgstr "Đã xóa thành công"
+
 #: src/views/preference/CertSettings.vue:27
 #, fuzzy
 msgid "Certificate Renewal Interval"
@@ -490,7 +496,7 @@ msgstr "Chứng chỉ SSL hợp lệ"
 msgid "Certificate renewed successfully"
 msgstr "Đã xóa thành công"
 
-#: src/views/certificate/CertificateEditor.vue:128
+#: src/views/certificate/components/CertificateEditor.vue:128
 #: src/views/site/cert/Cert.vue:60
 #, fuzzy
 msgid "Certificate Status"
@@ -499,7 +505,7 @@ msgstr[0] "Trạng thái chứng chỉ"
 msgstr[1] "Trạng thái chứng chỉ"
 
 #: src/routes/modules/certificates.ts:11
-#: src/views/certificate/CertificateList/Certificate.vue:13
+#: src/views/certificate/CertificateList/Certificate.vue:14
 #, fuzzy
 msgid "Certificates"
 msgstr "Chứng chỉ"
@@ -807,6 +813,7 @@ msgstr "Mô tả"
 
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:21
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
+#: src/views/certificate/components/RemoveCert.vue:87
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
 #: src/views/site/site_list/SiteList.vue:176
@@ -814,6 +821,11 @@ msgstr "Mô tả"
 msgid "Delete"
 msgstr "Xoá"
 
+#: src/views/certificate/components/RemoveCert.vue:92
+#, fuzzy
+msgid "Delete Certificate"
+msgstr "Gia hạn chứng chỉ SSL"
+
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:35
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:547
 msgid "Delete Permanently"
@@ -1003,7 +1015,7 @@ msgstr "Đã bật %{conf_name} trên %{node_name}"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:159
 #: src/views/site/site_edit/SiteEdit.vue:199
-#: src/views/site/site_list/columns.tsx:102 src/views/stream/StreamEdit.vue:182
+#: src/views/site/site_list/columns.tsx:111 src/views/stream/StreamEdit.vue:182
 #: src/views/stream/StreamList.vue:58 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Đã tắt"
@@ -1078,11 +1090,11 @@ msgid_plural "Documents"
 msgstr[0] "Bình luận"
 msgstr[1] "Bình luận"
 
-#: src/views/certificate/WildcardCertificate.vue:68
+#: src/views/certificate/components/WildcardCertificate.vue:68
 msgid "Domain"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:112
+#: src/views/certificate/components/CertificateEditor.vue:112
 msgid "Domains list is empty, try to reopen Auto Cert for %{config}"
 msgstr ""
 "Danh sách tên miền rỗng, hãy thử mở lại chức năng Tạo chứng chỉ tự động cho "
@@ -1258,7 +1270,7 @@ msgstr "Bật TLS"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:155
 #: src/views/site/site_edit/SiteEdit.vue:193
-#: src/views/site/site_list/columns.tsx:101
+#: src/views/site/site_list/columns.tsx:110
 #: src/views/stream/components/RightSettings.vue:81
 #: src/views/stream/StreamEdit.vue:176 src/views/stream/StreamList.vue:54
 #: src/views/user/userColumns.tsx:38
@@ -1472,6 +1484,11 @@ msgstr ""
 msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:66
+#, fuzzy
+msgid "Failed to delete certificate"
+msgstr "Nhận chứng chỉ"
+
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:63
 #: src/views/stream/components/RightSettings.vue:45
 #: src/views/stream/StreamList.vue:100
@@ -1590,6 +1607,11 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:48
+#, fuzzy
+msgid "Failed to revoke certificate"
+msgstr "Nhận chứng chỉ"
+
 #: src/views/site/site_edit/SiteEdit.vue:139
 #: src/views/stream/StreamEdit.vue:122
 msgid "Failed to save, syntax error(s) was detected in the configuration."
@@ -1771,6 +1793,12 @@ msgid ""
 "ban threshold minutes, the ip will be banned for a period of time."
 msgstr ""
 
+#: src/views/site/cert/components/AutoCertStepOne.vue:117
+msgid ""
+"If you want to automatically revoke the old certificate, please enable this "
+"option."
+msgstr ""
+
 #: src/views/preference/components/AddPasskey.vue:70
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr ""
@@ -1781,13 +1809,13 @@ msgid ""
 "need to enable this option."
 msgstr ""
 
-#: src/views/certificate/CertificateList/Certificate.vue:20
+#: src/views/certificate/CertificateList/Certificate.vue:22
 #, fuzzy
 msgid "Import"
 msgstr "Xuất"
 
 #: src/routes/modules/certificates.ts:46
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 #, fuzzy
 msgid "Import Certificate"
 msgstr "Chứng chỉ"
@@ -1917,12 +1945,12 @@ msgstr ""
 msgid "IP"
 msgstr ""
 
-#: src/views/certificate/CertificateList/Certificate.vue:28
+#: src/views/certificate/CertificateList/Certificate.vue:31
 #, fuzzy
 msgid "Issue wildcard certificate"
 msgstr "Gia hạn SSL"
 
-#: src/views/certificate/WildcardCertificate.vue:59
+#: src/views/certificate/components/WildcardCertificate.vue:59
 #, fuzzy
 msgid "Issue Wildcard Certificate"
 msgstr "Thêm chứng chỉ SSL"
@@ -1992,8 +2020,8 @@ msgstr "Bỏ trống nếu không thay đổi"
 msgid "Leave blank if you don't need this."
 msgstr "Bỏ trống nếu không thay đổi"
 
-#: src/views/certificate/CertificateEditor.vue:220
-#: src/views/certificate/CertificateEditor.vue:233
+#: src/views/certificate/components/CertificateEditor.vue:222
+#: src/views/certificate/components/CertificateEditor.vue:235
 #, fuzzy
 msgid "Leave blank will not change anything"
 msgstr "Bỏ trống nếu không thay đổi"
@@ -2048,7 +2076,7 @@ msgstr "Location"
 msgid "Locations"
 msgstr "Locations"
 
-#: src/views/certificate/CertificateEditor.vue:243
+#: src/views/certificate/components/CertificateEditor.vue:245
 #, fuzzy
 msgid "Log"
 msgstr "Log"
@@ -2084,7 +2112,7 @@ msgid ""
 msgstr ""
 
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:163
-#: src/views/site/site_list/columns.tsx:103
+#: src/views/site/site_list/columns.tsx:112
 msgid "Maintenance"
 msgstr ""
 
@@ -2164,7 +2192,7 @@ msgid "Modify"
 msgstr "Sửa"
 
 #: src/routes/modules/certificates.ts:36
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 #, fuzzy
 msgid "Modify Certificate"
 msgstr "Sửa chứng chỉ"
@@ -2184,8 +2212,8 @@ msgid "Multi-line Directive"
 msgstr "Single Directive"
 
 #: src/views/certificate/ACMEUser.vue:13
-#: src/views/certificate/CertificateEditor.vue:160
 #: src/views/certificate/CertificateList/certColumns.tsx:10
+#: src/views/certificate/components/CertificateEditor.vue:162
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:305
@@ -2238,7 +2266,7 @@ msgstr "Đường dẫn"
 msgid "New version released"
 msgstr "Đã có phiên bản mới"
 
-#: src/views/certificate/WildcardCertificate.vue:91
+#: src/views/certificate/components/WildcardCertificate.vue:91
 #: src/views/site/cert/components/ObtainCert.vue:211
 #: src/views/site/site_add/SiteAdd.vue:141
 msgid "Next"
@@ -2408,7 +2436,7 @@ msgid "Node"
 msgstr "Username"
 
 #: src/views/site/site_edit/RightSettings.vue:66
-#: src/views/site/site_list/columns.tsx:63
+#: src/views/site/site_list/columns.tsx:65
 #: src/views/stream/components/RightSettings.vue:90
 #: src/views/stream/StreamList.vue:30
 #, fuzzy
@@ -2761,6 +2789,10 @@ msgstr ""
 msgid "Please select at least one node to upgrade"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:27
+msgid "Please type \"Revoke\" to confirm"
+msgstr ""
+
 #: src/views/preference/ServerSettings.vue:21
 msgid "Port"
 msgstr ""
@@ -3050,8 +3082,8 @@ msgstr "Gia hạn chứng chỉ SSL"
 msgid "Renamed successfully"
 msgstr "Gia hạn chứng chỉ SSL"
 
-#: src/views/certificate/RenewCert.vue:45
-#: src/views/certificate/RenewCert.vue:49
+#: src/views/certificate/components/RenewCert.vue:45
+#: src/views/certificate/components/RenewCert.vue:49
 #, fuzzy
 msgid "Renew Certificate"
 msgstr "Gia hạn chứng chỉ SSL"
@@ -3066,8 +3098,8 @@ msgstr "Gia hạn chứng chỉ SSL thất bại"
 msgid "Renew Certificate Success"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 
-#: src/views/certificate/RenewCert.vue:27
-#: src/views/certificate/WildcardCertificate.vue:48
+#: src/views/certificate/components/RenewCert.vue:27
+#: src/views/certificate/components/WildcardCertificate.vue:48
 #, fuzzy
 msgid "Renew successfully"
 msgstr "Gia hạn chứng chỉ SSL"
@@ -3155,6 +3187,27 @@ msgstr "Lỗi phân tích cú pháp cấu hình Nginx"
 msgid "Restore this version"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:26
+#: src/views/certificate/components/RemoveCert.vue:95
+msgid "Revoke"
+msgstr ""
+
+#: src/views/site/cert/components/AutoCertStepOne.vue:114
+#, fuzzy
+msgid "Revoke Old Certificate"
+msgstr "Gia hạn chứng chỉ SSL"
+
+#: src/views/certificate/components/RemoveCert.vue:109
+#, fuzzy
+msgid "Revoke this certificate"
+msgstr "Gia hạn chứng chỉ SSL"
+
+#: src/views/certificate/components/RemoveCert.vue:117
+msgid ""
+"Revoking a certificate will affect any services currently using it. This "
+"action cannot be undone."
+msgstr ""
+
 #: src/views/preference/AuthSettings.vue:107
 msgid "RP Display Name"
 msgstr ""
@@ -3179,7 +3232,7 @@ msgstr "Running"
 #: src/components/ChatGPT/ChatGPT.vue:355
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:64
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
-#: src/views/certificate/CertificateEditor.vue:262
+#: src/views/certificate/components/CertificateEditor.vue:264
 #: src/views/config/components/ConfigName.vue:59
 #: src/views/config/ConfigEditor.vue:271
 #: src/views/preference/components/Passkey.vue:130
@@ -3245,7 +3298,7 @@ msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
-#: src/views/certificate/CertificateEditor.vue:49
+#: src/views/certificate/components/CertificateEditor.vue:49
 #: src/views/preference/Preference.vue:124
 #, fuzzy
 msgid "Save successfully"
@@ -3414,7 +3467,7 @@ msgstr ""
 msgid "Skip Installation"
 msgstr "Cài đặt"
 
-#: src/views/certificate/CertificateEditor.vue:211
+#: src/views/certificate/components/CertificateEditor.vue:213
 msgid "SSL Certificate Content"
 msgstr ""
 
@@ -3427,15 +3480,15 @@ msgstr ""
 msgid "SSL certificate file not found"
 msgstr "Không tìm thấy tệp tin"
 
-#: src/views/certificate/CertificateEditor.vue:224
+#: src/views/certificate/components/CertificateEditor.vue:226
 msgid "SSL Certificate Key Content"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:190
+#: src/views/certificate/components/CertificateEditor.vue:192
 msgid "SSL Certificate Key Path"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:175
+#: src/views/certificate/components/CertificateEditor.vue:177
 #: src/views/preference/ServerSettings.vue:36
 msgid "SSL Certificate Path"
 msgstr ""
@@ -3482,7 +3535,7 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/site/site_list/columns.tsx:80 src/views/stream/StreamList.vue:47
+#: src/views/site/site_list/columns.tsx:89 src/views/stream/StreamList.vue:47
 msgid "Status"
 msgstr "Trạng thái"
 
@@ -3611,7 +3664,7 @@ msgstr ""
 msgid "Sync strategy"
 msgstr "Gia hạn chứng chỉ SSL"
 
-#: src/views/certificate/CertificateEditor.vue:204
+#: src/views/certificate/components/CertificateEditor.vue:206
 msgid "Sync to"
 msgstr ""
 
@@ -3629,7 +3682,7 @@ msgstr "Thông tin"
 msgid "System Backup"
 msgstr "Thông tin"
 
-#: src/views/certificate/ACMEUserSelector.vue:88
+#: src/views/certificate/components/ACMEUserSelector.vue:88
 msgid "System Initial User"
 msgstr ""
 
@@ -3681,11 +3734,11 @@ msgid ""
 "dashes, colons, and dots."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:214
+#: src/views/certificate/components/CertificateEditor.vue:216
 msgid "The input is not a SSL Certificate"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:227
+#: src/views/certificate/components/CertificateEditor.vue:229
 msgid "The input is not a SSL Certificate Key"
 msgstr ""
 
@@ -3711,11 +3764,11 @@ msgstr ""
 msgid "The parameter of server_name is required"
 msgstr "Tham số server_name là bắt buộc"
 
-#: src/views/certificate/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:181
 msgid "The path exists, but the file is not a certificate"
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:194
+#: src/views/certificate/components/CertificateEditor.vue:196
 msgid "The path exists, but the file is not a private key"
 msgstr ""
 
@@ -3761,17 +3814,17 @@ msgid ""
 "lose access to your account."
 msgstr ""
 
-#: src/views/certificate/CertificateEditor.vue:102
+#: src/views/certificate/components/CertificateEditor.vue:102
 msgid "This Auto Cert item is invalid, please remove it."
 msgstr "Mục Chứng chỉ tự động này không hợp lệ, vui lòng xóa nó"
 
-#: src/views/certificate/CertificateEditor.vue:92
+#: src/views/certificate/components/CertificateEditor.vue:92
 msgid "This certificate is managed by Nginx UI"
 msgstr "Chứng chỉ này được quản lý bởi Nginx UI"
 
-#: src/views/certificate/CertificateEditor.vue:163
-#: src/views/certificate/CertificateEditor.vue:177
-#: src/views/certificate/CertificateEditor.vue:192
+#: src/views/certificate/components/CertificateEditor.vue:165
+#: src/views/certificate/components/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:194
 msgid "This field is required"
 msgstr ""
 
@@ -3795,6 +3848,12 @@ msgid ""
 "This field should only contain letters, unicode characters, numbers, and -_."
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:103
+msgid ""
+"This operation will only remove the certificate from the database. The "
+"certificate files on the file system will not be deleted."
+msgstr ""
+
 #: src/views/system/Backup/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -3838,6 +3897,10 @@ msgstr ""
 msgid "Title"
 msgstr "Tiêu đề"
 
+#: src/views/certificate/components/RemoveCert.vue:121
+msgid "To confirm revocation, please type \"Revoke\" in the field below:"
+msgstr ""
+
 #: src/views/preference/components/TOTP.vue:68
 msgid ""
 "To enable it, you need to install the Google or Microsoft Authenticator app "
@@ -3920,7 +3983,7 @@ msgstr "Cập nhật thành công"
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:75
-#: src/views/site/site_list/columns.tsx:110
+#: src/views/site/site_list/columns.tsx:82
 #: src/views/stream/components/RightSettings.vue:99
 #: src/views/stream/StreamList.vue:67 src/views/user/userColumns.tsx:54
 msgid "Updated at"
@@ -4081,6 +4144,10 @@ msgstr ""
 msgid "WebAuthn settings are not configured"
 msgstr ""
 
+#: src/views/certificate/components/RemoveCert.vue:54
+msgid "WebSocket connection error"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:83
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "

+ 106 - 45
app/src/language/zh_CN/app.po

@@ -3,7 +3,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "POT-Creation-Date: \n"
-"PO-Revision-Date: 2025-04-09 22:02+0800\n"
+"PO-Revision-Date: 2025-04-10 16:13+0800\n"
 "Last-Translator: 0xJacky <me@jackyu.cn>\n"
 "Language-Team: Chinese (Simplified Han script) <https://weblate.nginxui.com/"
 "projects/nginx-ui/frontend/zh_Hans/>\n"
@@ -36,7 +36,7 @@ msgid "Access Logs"
 msgstr "访问日志"
 
 #: src/routes/modules/certificates.ts:20 src/views/certificate/ACMEUser.vue:113
-#: src/views/certificate/ACMEUserSelector.vue:85
+#: src/views/certificate/components/ACMEUserSelector.vue:85
 msgid "ACME User"
 msgstr "ACME 用户"
 
@@ -50,7 +50,7 @@ msgstr "ACME 用户"
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
 #: src/views/preference/components/ExternalNotify/columns.ts:46
-#: src/views/site/site_list/columns.tsx:117 src/views/stream/StreamList.vue:74
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/StreamList.vue:74
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "操作"
@@ -274,7 +274,7 @@ msgstr "自动重启"
 msgid "Automatically indexed from site and stream configurations."
 msgstr "自动索引站点和 Stream 的配置文件。"
 
-#: src/views/certificate/CertificateEditor.vue:255
+#: src/views/certificate/components/CertificateEditor.vue:257
 #: src/views/config/ConfigEditor.vue:262 src/views/config/ConfigList.vue:112
 #: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:285
@@ -445,6 +445,11 @@ msgstr "证书解析错误"
 msgid "Certificate path is empty"
 msgstr "证书路径为空"
 
+#: src/views/certificate/components/RemoveCert.vue:41
+#: src/views/certificate/components/RemoveCert.vue:61
+msgid "Certificate removed successfully"
+msgstr "成功删除证书"
+
 #: src/views/preference/CertSettings.vue:27
 msgid "Certificate Renewal Interval"
 msgstr "证书续期间隔"
@@ -453,14 +458,14 @@ msgstr "证书续期间隔"
 msgid "Certificate renewed successfully"
 msgstr "证书更新成功"
 
-#: src/views/certificate/CertificateEditor.vue:128
+#: src/views/certificate/components/CertificateEditor.vue:128
 #: src/views/site/cert/Cert.vue:60
 msgid "Certificate Status"
 msgid_plural "Certificates Status"
 msgstr[0] "证书状态"
 
 #: src/routes/modules/certificates.ts:11
-#: src/views/certificate/CertificateList/Certificate.vue:13
+#: src/views/certificate/CertificateList/Certificate.vue:14
 msgid "Certificates"
 msgstr "证书"
 
@@ -753,6 +758,7 @@ msgstr "解密失败"
 
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:21
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
+#: src/views/certificate/components/RemoveCert.vue:87
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
 #: src/views/site/site_list/SiteList.vue:176
@@ -760,6 +766,10 @@ msgstr "解密失败"
 msgid "Delete"
 msgstr "删除"
 
+#: src/views/certificate/components/RemoveCert.vue:92
+msgid "Delete Certificate"
+msgstr "删除证书"
+
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:35
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:547
 msgid "Delete Permanently"
@@ -925,7 +935,7 @@ msgstr "在 %{node} 上禁用 %{name} 成功"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:159
 #: src/views/site/site_edit/SiteEdit.vue:199
-#: src/views/site/site_list/columns.tsx:102 src/views/stream/StreamEdit.vue:182
+#: src/views/site/site_list/columns.tsx:111 src/views/stream/StreamEdit.vue:182
 #: src/views/stream/StreamList.vue:58 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "禁用"
@@ -992,11 +1002,11 @@ msgid "Document"
 msgid_plural "Documents"
 msgstr[0] "文档"
 
-#: src/views/certificate/WildcardCertificate.vue:68
+#: src/views/certificate/components/WildcardCertificate.vue:68
 msgid "Domain"
 msgstr "域名"
 
-#: src/views/certificate/CertificateEditor.vue:112
+#: src/views/certificate/components/CertificateEditor.vue:112
 msgid "Domains list is empty, try to reopen Auto Cert for %{config}"
 msgstr "域名列表为空,请尝试为 %{config} 重新打开证书自动续期"
 
@@ -1151,7 +1161,7 @@ msgstr "启用 TOTP"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:155
 #: src/views/site/site_edit/SiteEdit.vue:193
-#: src/views/site/site_list/columns.tsx:101
+#: src/views/site/site_list/columns.tsx:110
 #: src/views/stream/components/RightSettings.vue:81
 #: src/views/stream/StreamEdit.vue:176 src/views/stream/StreamList.vue:54
 #: src/views/user/userColumns.tsx:38
@@ -1342,6 +1352,10 @@ msgstr "解密 Nginx 目录失败:{0}"
 msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr "解密 Nginx UI 目录失败:{0}"
 
+#: src/views/certificate/components/RemoveCert.vue:66
+msgid "Failed to delete certificate"
+msgstr "删除证书失败"
+
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:63
 #: src/views/stream/components/RightSettings.vue:45
 #: src/views/stream/StreamList.vue:100
@@ -1446,6 +1460,10 @@ msgstr "恢复 Nginx 配置失败:{0}"
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr "恢复 Nginx UI 文件失败:{0}"
 
+#: src/views/certificate/components/RemoveCert.vue:48
+msgid "Failed to revoke certificate"
+msgstr "证书撤销失败"
+
 #: src/views/site/site_edit/SiteEdit.vue:139
 #: src/views/stream/StreamEdit.vue:122
 msgid "Failed to save, syntax error(s) was detected in the configuration."
@@ -1621,6 +1639,12 @@ msgstr ""
 "如果某个 IP 的登录失败次数达到禁用阈值分钟内的最大尝试次数,该 IP 将被禁止登"
 "录一段时间。"
 
+#: src/views/site/cert/components/AutoCertStepOne.vue:117
+msgid ""
+"If you want to automatically revoke the old certificate, please enable this "
+"option."
+msgstr "如果要自动撤销旧证书,请启用此选项。"
+
 #: src/views/preference/components/AddPasskey.vue:70
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr "如果您的浏览器支持 WebAuthn Passkey,则会出现一个对话框。"
@@ -1631,12 +1655,12 @@ msgid ""
 "need to enable this option."
 msgstr "如果您的域名有 CNAME 记录且无法获取证书,则需要启用此选项。"
 
-#: src/views/certificate/CertificateList/Certificate.vue:20
+#: src/views/certificate/CertificateList/Certificate.vue:22
 msgid "Import"
 msgstr "导入"
 
 #: src/routes/modules/certificates.ts:46
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Import Certificate"
 msgstr "导入证书"
 
@@ -1758,11 +1782,11 @@ msgstr "安全令牌格式无效"
 msgid "IP"
 msgstr "IP"
 
-#: src/views/certificate/CertificateList/Certificate.vue:28
+#: src/views/certificate/CertificateList/Certificate.vue:31
 msgid "Issue wildcard certificate"
 msgstr "签发通配符证书"
 
-#: src/views/certificate/WildcardCertificate.vue:59
+#: src/views/certificate/components/WildcardCertificate.vue:59
 msgid "Issue Wildcard Certificate"
 msgstr "颁发通配符证书"
 
@@ -1826,8 +1850,8 @@ msgstr "如果不想修改,请留空"
 msgid "Leave blank if you don't need this."
 msgstr "如果不需要,请留空。"
 
-#: src/views/certificate/CertificateEditor.vue:220
-#: src/views/certificate/CertificateEditor.vue:233
+#: src/views/certificate/components/CertificateEditor.vue:222
+#: src/views/certificate/components/CertificateEditor.vue:235
 msgid "Leave blank will not change anything"
 msgstr "留空不做任何更改"
 
@@ -1877,7 +1901,7 @@ msgstr "Location"
 msgid "Locations"
 msgstr "Locations"
 
-#: src/views/certificate/CertificateEditor.vue:243
+#: src/views/certificate/components/CertificateEditor.vue:245
 msgid "Log"
 msgstr "日志"
 
@@ -1916,7 +1940,7 @@ msgstr ""
 "照您设置的时间间隔(以分钟为单位)执行 logrotate 命令。"
 
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:163
-#: src/views/site/site_list/columns.tsx:103
+#: src/views/site/site_list/columns.tsx:112
 msgid "Maintenance"
 msgstr "维护模式"
 
@@ -1990,7 +2014,7 @@ msgid "Modify"
 msgstr "修改"
 
 #: src/routes/modules/certificates.ts:36
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Modify Certificate"
 msgstr "修改证书"
 
@@ -2007,8 +2031,8 @@ msgid "Multi-line Directive"
 msgstr "多行指令"
 
 #: src/views/certificate/ACMEUser.vue:13
-#: src/views/certificate/CertificateEditor.vue:160
 #: src/views/certificate/CertificateList/certColumns.tsx:10
+#: src/views/certificate/components/CertificateEditor.vue:162
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:305
@@ -2058,7 +2082,7 @@ msgstr "新路径"
 msgid "New version released"
 msgstr "新版本发布"
 
-#: src/views/certificate/WildcardCertificate.vue:91
+#: src/views/certificate/components/WildcardCertificate.vue:91
 #: src/views/site/cert/components/ObtainCert.vue:211
 #: src/views/site/site_add/SiteAdd.vue:141
 msgid "Next"
@@ -2216,7 +2240,7 @@ msgid "Node"
 msgstr "节点"
 
 #: src/views/site/site_edit/RightSettings.vue:66
-#: src/views/site/site_list/columns.tsx:63
+#: src/views/site/site_list/columns.tsx:65
 #: src/views/stream/components/RightSettings.vue:90
 #: src/views/stream/StreamList.vue:30
 msgid "Node Group"
@@ -2553,6 +2577,10 @@ msgstr "请至少选择一个节点重启 Nginx"
 msgid "Please select at least one node to upgrade"
 msgstr "请至少选择一个节点进行升级"
 
+#: src/views/certificate/components/RemoveCert.vue:27
+msgid "Please type \"Revoke\" to confirm"
+msgstr "请键入 \"撤销 \"确认"
+
 #: src/views/preference/ServerSettings.vue:21
 msgid "Port"
 msgstr "端口"
@@ -2812,8 +2840,8 @@ msgstr "重命名成功"
 msgid "Renamed successfully"
 msgstr "重命名成功"
 
-#: src/views/certificate/RenewCert.vue:45
-#: src/views/certificate/RenewCert.vue:49
+#: src/views/certificate/components/RenewCert.vue:45
+#: src/views/certificate/components/RenewCert.vue:49
 msgid "Renew Certificate"
 msgstr "更新证书"
 
@@ -2825,8 +2853,8 @@ msgstr "证书续期错误"
 msgid "Renew Certificate Success"
 msgstr "证书续期成功"
 
-#: src/views/certificate/RenewCert.vue:27
-#: src/views/certificate/WildcardCertificate.vue:48
+#: src/views/certificate/components/RenewCert.vue:27
+#: src/views/certificate/components/WildcardCertificate.vue:48
 msgid "Renew successfully"
 msgstr "更新成功"
 
@@ -2903,6 +2931,25 @@ msgstr "恢复 Nginx UI 配置"
 msgid "Restore this version"
 msgstr "恢复此版本"
 
+#: src/views/certificate/components/RemoveCert.vue:26
+#: src/views/certificate/components/RemoveCert.vue:95
+msgid "Revoke"
+msgstr "撤销"
+
+#: src/views/site/cert/components/AutoCertStepOne.vue:114
+msgid "Revoke Old Certificate"
+msgstr "撤销旧证书"
+
+#: src/views/certificate/components/RemoveCert.vue:109
+msgid "Revoke this certificate"
+msgstr "撤销该证书"
+
+#: src/views/certificate/components/RemoveCert.vue:117
+msgid ""
+"Revoking a certificate will affect any services currently using it. This "
+"action cannot be undone."
+msgstr "撤销证书将影响当前使用该证书的任何服务。该操作无法撤销。"
+
 #: src/views/preference/AuthSettings.vue:107
 msgid "RP Display Name"
 msgstr "依赖方显示名称"
@@ -2926,7 +2973,7 @@ msgstr "运行中"
 #: src/components/ChatGPT/ChatGPT.vue:355
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:64
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
-#: src/views/certificate/CertificateEditor.vue:262
+#: src/views/certificate/components/CertificateEditor.vue:264
 #: src/views/config/components/ConfigName.vue:59
 #: src/views/config/ConfigEditor.vue:271
 #: src/views/preference/components/Passkey.vue:130
@@ -2984,7 +3031,7 @@ msgstr "成功将站点 %{name} 保存到 %{node} 中"
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
-#: src/views/certificate/CertificateEditor.vue:49
+#: src/views/certificate/components/CertificateEditor.vue:49
 #: src/views/preference/Preference.vue:124
 msgid "Save successfully"
 msgstr "保存成功"
@@ -3145,7 +3192,7 @@ msgstr "Sites-enabled 目录不存在"
 msgid "Skip Installation"
 msgstr "跳过安装"
 
-#: src/views/certificate/CertificateEditor.vue:211
+#: src/views/certificate/components/CertificateEditor.vue:213
 msgid "SSL Certificate Content"
 msgstr "SSL 证书内容"
 
@@ -3157,15 +3204,15 @@ msgstr "SSL 证书文件必须位于 Nginx 配置目录下:{0}"
 msgid "SSL certificate file not found"
 msgstr "未找到 SSL 证书文件"
 
-#: src/views/certificate/CertificateEditor.vue:224
+#: src/views/certificate/components/CertificateEditor.vue:226
 msgid "SSL Certificate Key Content"
 msgstr "SSL 证书密钥内容"
 
-#: src/views/certificate/CertificateEditor.vue:190
+#: src/views/certificate/components/CertificateEditor.vue:192
 msgid "SSL Certificate Key Path"
 msgstr "SSL证书密钥路径"
 
-#: src/views/certificate/CertificateEditor.vue:175
+#: src/views/certificate/components/CertificateEditor.vue:177
 #: src/views/preference/ServerSettings.vue:36
 msgid "SSL Certificate Path"
 msgstr "SSL证书路径"
@@ -3209,7 +3256,7 @@ msgstr "开始还原"
 #: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/site/site_list/columns.tsx:80 src/views/stream/StreamList.vue:47
+#: src/views/site/site_list/columns.tsx:89 src/views/stream/StreamList.vue:47
 msgid "Status"
 msgstr "状态"
 
@@ -3326,7 +3373,7 @@ msgstr "同步节点"
 msgid "Sync strategy"
 msgstr "同步策略"
 
-#: src/views/certificate/CertificateEditor.vue:204
+#: src/views/certificate/components/CertificateEditor.vue:206
 msgid "Sync to"
 msgstr "同步到"
 
@@ -3343,7 +3390,7 @@ msgstr "系统"
 msgid "System Backup"
 msgstr "系统备份"
 
-#: src/views/certificate/ACMEUserSelector.vue:88
+#: src/views/certificate/components/ACMEUserSelector.vue:88
 msgid "System Initial User"
 msgstr "系统初始用户"
 
@@ -3391,11 +3438,11 @@ msgid ""
 "dashes, colons, and dots."
 msgstr "ICP 备案号只能包含字母、单码、数字、连字符、破折号、冒号和点。"
 
-#: src/views/certificate/CertificateEditor.vue:214
+#: src/views/certificate/components/CertificateEditor.vue:216
 msgid "The input is not a SSL Certificate"
 msgstr "输入的内容不是 SSL 证书"
 
-#: src/views/certificate/CertificateEditor.vue:227
+#: src/views/certificate/components/CertificateEditor.vue:229
 msgid "The input is not a SSL Certificate Key"
 msgstr "输入的内容不是 SSL 证书密钥"
 
@@ -3420,11 +3467,11 @@ msgstr "节点名称只能包含字母、统一码、数字、连字符、破折
 msgid "The parameter of server_name is required"
 msgstr "必须为 server_name 指令指明参数"
 
-#: src/views/certificate/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:181
 msgid "The path exists, but the file is not a certificate"
 msgstr "路径存在,但文件不是证书"
 
-#: src/views/certificate/CertificateEditor.vue:194
+#: src/views/certificate/components/CertificateEditor.vue:196
 msgid "The path exists, but the file is not a private key"
 msgstr "路径存在,但文件不是私钥"
 
@@ -3472,17 +3519,17 @@ msgstr ""
 "这些代码是在您丢失密码和双重身份验证方式时,访问账户的最后手段。如果找不到这"
 "些代码,您将无法再访问您的账户。"
 
-#: src/views/certificate/CertificateEditor.vue:102
+#: src/views/certificate/components/CertificateEditor.vue:102
 msgid "This Auto Cert item is invalid, please remove it."
 msgstr "这个证书自动续期项目是无效的,请删除。"
 
-#: src/views/certificate/CertificateEditor.vue:92
+#: src/views/certificate/components/CertificateEditor.vue:92
 msgid "This certificate is managed by Nginx UI"
 msgstr "该证书由 Nginx UI 托管"
 
-#: src/views/certificate/CertificateEditor.vue:163
-#: src/views/certificate/CertificateEditor.vue:177
-#: src/views/certificate/CertificateEditor.vue:192
+#: src/views/certificate/components/CertificateEditor.vue:165
+#: src/views/certificate/components/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:194
 msgid "This field is required"
 msgstr "此字段必填"
 
@@ -3504,6 +3551,12 @@ msgid ""
 "This field should only contain letters, unicode characters, numbers, and -_."
 msgstr "该字段只能包含字母、unicode 字符、数字和 -_。"
 
+#: src/views/certificate/components/RemoveCert.vue:103
+msgid ""
+"This operation will only remove the certificate from the database. The "
+"certificate files on the file system will not be deleted."
+msgstr "此操作只会从数据库中删除证书。文件系统中的证书文件不会被删除。"
+
 #: src/views/system/Backup/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -3547,6 +3600,10 @@ msgstr "提示"
 msgid "Title"
 msgstr "标题"
 
+#: src/views/certificate/components/RemoveCert.vue:121
+msgid "To confirm revocation, please type \"Revoke\" in the field below:"
+msgstr "要确认撤销,请在下面的字段中输入 \"撤销\":"
+
 #: src/views/preference/components/TOTP.vue:68
 msgid ""
 "To enable it, you need to install the Google or Microsoft Authenticator app "
@@ -3630,7 +3687,7 @@ msgstr "更新成功"
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:75
-#: src/views/site/site_list/columns.tsx:110
+#: src/views/site/site_list/columns.tsx:82
 #: src/views/stream/components/RightSettings.vue:99
 #: src/views/stream/StreamList.vue:67 src/views/user/userColumns.tsx:54
 msgid "Updated at"
@@ -3780,6 +3837,10 @@ msgstr "Webauthn"
 msgid "WebAuthn settings are not configured"
 msgstr "WebAuthn 未配置"
 
+#: src/views/certificate/components/RemoveCert.vue:54
+msgid "WebSocket connection error"
+msgstr "WebSocket 连接错误"
+
 #: src/views/certificate/ACMEUser.vue:83
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "

+ 123 - 50
app/src/language/zh_TW/app.po

@@ -40,7 +40,7 @@ msgid "Access Logs"
 msgstr "訪問日誌"
 
 #: src/routes/modules/certificates.ts:20 src/views/certificate/ACMEUser.vue:113
-#: src/views/certificate/ACMEUserSelector.vue:85
+#: src/views/certificate/components/ACMEUserSelector.vue:85
 msgid "ACME User"
 msgstr "ACME 用戶"
 
@@ -54,7 +54,7 @@ msgstr "ACME 用戶"
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
 #: src/views/preference/components/ExternalNotify/columns.ts:46
-#: src/views/site/site_list/columns.tsx:117 src/views/stream/StreamList.vue:74
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/StreamList.vue:74
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "操作"
@@ -278,7 +278,7 @@ msgstr "自動重新啟動"
 msgid "Automatically indexed from site and stream configurations."
 msgstr "自動從網站和串流配置中索引。"
 
-#: src/views/certificate/CertificateEditor.vue:255
+#: src/views/certificate/components/CertificateEditor.vue:257
 #: src/views/config/ConfigEditor.vue:262 src/views/config/ConfigList.vue:112
 #: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:285
@@ -449,6 +449,12 @@ msgstr "證書解析錯誤"
 msgid "Certificate path is empty"
 msgstr "證書路徑為空"
 
+#: src/views/certificate/components/RemoveCert.vue:41
+#: src/views/certificate/components/RemoveCert.vue:61
+#, fuzzy
+msgid "Certificate removed successfully"
+msgstr "憑證更新成功"
+
 #: src/views/preference/CertSettings.vue:27
 msgid "Certificate Renewal Interval"
 msgstr "憑證更新間隔"
@@ -457,14 +463,14 @@ msgstr "憑證更新間隔"
 msgid "Certificate renewed successfully"
 msgstr "憑證更新成功"
 
-#: src/views/certificate/CertificateEditor.vue:128
+#: src/views/certificate/components/CertificateEditor.vue:128
 #: src/views/site/cert/Cert.vue:60
 msgid "Certificate Status"
 msgid_plural "Certificates Status"
 msgstr[0] "憑證狀態"
 
 #: src/routes/modules/certificates.ts:11
-#: src/views/certificate/CertificateList/Certificate.vue:13
+#: src/views/certificate/CertificateList/Certificate.vue:14
 msgid "Certificates"
 msgstr "憑證"
 
@@ -503,8 +509,9 @@ msgstr "再次檢查"
 msgid ""
 "Check if HTTPS is enabled. Using HTTP outside localhost is insecure and "
 "prevents using Passkeys and clipboard features."
-msgstr "檢查是否啟用了 HTTPS。在本地主機之外使用 HTTP "
-"是不安全的,並且會阻止使用通行證和剪貼簿功能。"
+msgstr ""
+"檢查是否啟用了 HTTPS。在本地主機之外使用 HTTP 是不安全的,並且會阻止使用通行"
+"證和剪貼簿功能。"
 
 #: src/views/system/SelfCheck/tasks/backend/index.ts:16
 msgid "Check if the nginx.conf includes the sites-enabled directory."
@@ -685,7 +692,8 @@ msgstr "創建資料夾"
 msgid ""
 "Create system backups including Nginx configuration and Nginx UI settings. "
 "Backup files will be automatically downloaded to your computer."
-msgstr "建立系統備份,包括 Nginx 配置與 Nginx UI 設定。備份檔案將自動下載至您的電腦。"
+msgstr ""
+"建立系統備份,包括 Nginx 配置與 Nginx UI 設定。備份檔案將自動下載至您的電腦。"
 
 #: src/views/environments/group/columns.ts:31
 #: src/views/notification/notificationColumns.tsx:59
@@ -757,6 +765,7 @@ msgstr "解密失敗"
 
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:21
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
+#: src/views/certificate/components/RemoveCert.vue:87
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
 #: src/views/site/site_list/SiteList.vue:176
@@ -764,6 +773,11 @@ msgstr "解密失敗"
 msgid "Delete"
 msgstr "刪除"
 
+#: src/views/certificate/components/RemoveCert.vue:92
+#, fuzzy
+msgid "Delete Certificate"
+msgstr "更換憑證"
+
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:35
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:547
 msgid "Delete Permanently"
@@ -929,7 +943,7 @@ msgstr "已成功從 %{node} 停用串流 %{name}"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:159
 #: src/views/site/site_edit/SiteEdit.vue:199
-#: src/views/site/site_list/columns.tsx:102 src/views/stream/StreamEdit.vue:182
+#: src/views/site/site_list/columns.tsx:111 src/views/stream/StreamEdit.vue:182
 #: src/views/stream/StreamList.vue:58 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "停用"
@@ -996,11 +1010,11 @@ msgid "Document"
 msgid_plural "Documents"
 msgstr[0] "档案"
 
-#: src/views/certificate/WildcardCertificate.vue:68
+#: src/views/certificate/components/WildcardCertificate.vue:68
 msgid "Domain"
 msgstr "網域"
 
-#: src/views/certificate/CertificateEditor.vue:112
+#: src/views/certificate/components/CertificateEditor.vue:112
 msgid "Domains list is empty, try to reopen Auto Cert for %{config}"
 msgstr "網域列表為空,請嘗試重新開啟 %{config} 的自動憑證"
 
@@ -1155,7 +1169,7 @@ msgstr "啟用 TOTP"
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:155
 #: src/views/site/site_edit/SiteEdit.vue:193
-#: src/views/site/site_list/columns.tsx:101
+#: src/views/site/site_list/columns.tsx:110
 #: src/views/stream/components/RightSettings.vue:81
 #: src/views/stream/StreamEdit.vue:176 src/views/stream/StreamList.vue:54
 #: src/views/user/userColumns.tsx:38
@@ -1346,6 +1360,11 @@ msgstr "解密Nginx目錄失敗:{0}"
 msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr "解密Nginx UI目錄失敗:{0}"
 
+#: src/views/certificate/components/RemoveCert.vue:66
+#, fuzzy
+msgid "Failed to delete certificate"
+msgstr "獲取憑證失敗"
+
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:63
 #: src/views/stream/components/RightSettings.vue:45
 #: src/views/stream/StreamList.vue:100
@@ -1450,6 +1469,11 @@ msgstr "恢復Nginx配置失敗:{0}"
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr "無法恢復Nginx UI文件:{0}"
 
+#: src/views/certificate/components/RemoveCert.vue:48
+#, fuzzy
+msgid "Failed to revoke certificate"
+msgstr "獲取憑證失敗"
+
 #: src/views/site/site_edit/SiteEdit.vue:139
 #: src/views/stream/StreamEdit.vue:122
 msgid "Failed to save, syntax error(s) was detected in the configuration."
@@ -1624,6 +1648,13 @@ msgstr ""
 "如果來自某個 IP 的登錄失敗次數在禁止閾值分鐘內達到最大嘗試次數,該 IP 將被禁"
 "止一段時間。"
 
+#: src/views/site/cert/components/AutoCertStepOne.vue:117
+#, fuzzy
+msgid ""
+"If you want to automatically revoke the old certificate, please enable this "
+"option."
+msgstr "如果您的域名有 CNAME 記錄且無法獲取證書,您需要啟用此選項。"
+
 #: src/views/preference/components/AddPasskey.vue:70
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr "如果您的瀏覽器支援 WebAuthn 通行密鑰,將會顯示一個對話框。"
@@ -1634,12 +1665,12 @@ msgid ""
 "need to enable this option."
 msgstr "如果您的域名有 CNAME 記錄且無法獲取證書,您需要啟用此選項。"
 
-#: src/views/certificate/CertificateList/Certificate.vue:20
+#: src/views/certificate/CertificateList/Certificate.vue:22
 msgid "Import"
 msgstr "導入"
 
 #: src/routes/modules/certificates.ts:46
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Import Certificate"
 msgstr "導入憑證"
 
@@ -1761,11 +1792,11 @@ msgstr "無效的安全令牌格式"
 msgid "IP"
 msgstr "IP"
 
-#: src/views/certificate/CertificateList/Certificate.vue:28
+#: src/views/certificate/CertificateList/Certificate.vue:31
 msgid "Issue wildcard certificate"
 msgstr "發行萬用字元憑證"
 
-#: src/views/certificate/WildcardCertificate.vue:59
+#: src/views/certificate/components/WildcardCertificate.vue:59
 msgid "Issue Wildcard Certificate"
 msgstr "簽發萬用字元憑證"
 
@@ -1829,8 +1860,8 @@ msgstr "留空表示不修改"
 msgid "Leave blank if you don't need this."
 msgstr "留空表示不需要此項目。"
 
-#: src/views/certificate/CertificateEditor.vue:220
-#: src/views/certificate/CertificateEditor.vue:233
+#: src/views/certificate/components/CertificateEditor.vue:222
+#: src/views/certificate/components/CertificateEditor.vue:235
 msgid "Leave blank will not change anything"
 msgstr "留空將不會改變任何內容"
 
@@ -1880,7 +1911,7 @@ msgstr "Location"
 msgid "Locations"
 msgstr "Locations"
 
-#: src/views/certificate/CertificateEditor.vue:243
+#: src/views/certificate/components/CertificateEditor.vue:245
 msgid "Log"
 msgstr "日誌"
 
@@ -1919,7 +1950,7 @@ msgstr ""
 "鐘間隔執行 logrotate 命令。"
 
 #: src/views/site/site_edit/components/SiteStatusSegmented.vue:163
-#: src/views/site/site_list/columns.tsx:103
+#: src/views/site/site_list/columns.tsx:112
 msgid "Maintenance"
 msgstr "維護"
 
@@ -1992,7 +2023,7 @@ msgid "Modify"
 msgstr "修改"
 
 #: src/routes/modules/certificates.ts:36
-#: src/views/certificate/CertificateEditor.vue:85
+#: src/views/certificate/components/CertificateEditor.vue:85
 msgid "Modify Certificate"
 msgstr "修改憑證"
 
@@ -2009,8 +2040,8 @@ msgid "Multi-line Directive"
 msgstr "多行指令"
 
 #: src/views/certificate/ACMEUser.vue:13
-#: src/views/certificate/CertificateEditor.vue:160
 #: src/views/certificate/CertificateList/certColumns.tsx:10
+#: src/views/certificate/components/CertificateEditor.vue:162
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:305
@@ -2060,7 +2091,7 @@ msgstr "新路徑"
 msgid "New version released"
 msgstr "新版本發布"
 
-#: src/views/certificate/WildcardCertificate.vue:91
+#: src/views/certificate/components/WildcardCertificate.vue:91
 #: src/views/site/cert/components/ObtainCert.vue:211
 #: src/views/site/site_add/SiteAdd.vue:141
 msgid "Next"
@@ -2218,7 +2249,7 @@ msgid "Node"
 msgstr "節點"
 
 #: src/views/site/site_edit/RightSettings.vue:66
-#: src/views/site/site_list/columns.tsx:63
+#: src/views/site/site_list/columns.tsx:65
 #: src/views/stream/components/RightSettings.vue:90
 #: src/views/stream/StreamList.vue:30
 msgid "Node Group"
@@ -2555,6 +2586,10 @@ msgstr "請至少選擇一個節點以重啟Nginx"
 msgid "Please select at least one node to upgrade"
 msgstr "請至少選擇一個節點進行升級"
 
+#: src/views/certificate/components/RemoveCert.vue:27
+msgid "Please type \"Revoke\" to confirm"
+msgstr ""
+
 #: src/views/preference/ServerSettings.vue:21
 msgid "Port"
 msgstr "監聽埠"
@@ -2813,8 +2848,8 @@ msgstr "重命名成功"
 msgid "Renamed successfully"
 msgstr "重新命名成功"
 
-#: src/views/certificate/RenewCert.vue:45
-#: src/views/certificate/RenewCert.vue:49
+#: src/views/certificate/components/RenewCert.vue:45
+#: src/views/certificate/components/RenewCert.vue:49
 msgid "Renew Certificate"
 msgstr "更換憑證"
 
@@ -2826,8 +2861,8 @@ msgstr "更新憑證錯誤"
 msgid "Renew Certificate Success"
 msgstr "更新憑證成功"
 
-#: src/views/certificate/RenewCert.vue:27
-#: src/views/certificate/WildcardCertificate.vue:48
+#: src/views/certificate/components/RenewCert.vue:27
+#: src/views/certificate/components/WildcardCertificate.vue:48
 msgid "Renew successfully"
 msgstr "更新成功"
 
@@ -2904,6 +2939,27 @@ msgstr "恢復Nginx UI配置"
 msgid "Restore this version"
 msgstr "恢復此版本"
 
+#: src/views/certificate/components/RemoveCert.vue:26
+#: src/views/certificate/components/RemoveCert.vue:95
+msgid "Revoke"
+msgstr ""
+
+#: src/views/site/cert/components/AutoCertStepOne.vue:114
+#, fuzzy
+msgid "Revoke Old Certificate"
+msgstr "更換憑證"
+
+#: src/views/certificate/components/RemoveCert.vue:109
+#, fuzzy
+msgid "Revoke this certificate"
+msgstr "更換憑證"
+
+#: src/views/certificate/components/RemoveCert.vue:117
+msgid ""
+"Revoking a certificate will affect any services currently using it. This "
+"action cannot be undone."
+msgstr ""
+
 #: src/views/preference/AuthSettings.vue:107
 msgid "RP Display Name"
 msgstr "RP 顯示名稱"
@@ -2927,7 +2983,7 @@ msgstr "執行中"
 #: src/components/ChatGPT/ChatGPT.vue:355
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:64
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
-#: src/views/certificate/CertificateEditor.vue:262
+#: src/views/certificate/components/CertificateEditor.vue:264
 #: src/views/config/components/ConfigName.vue:59
 #: src/views/config/ConfigEditor.vue:271
 #: src/views/preference/components/Passkey.vue:130
@@ -2985,7 +3041,7 @@ msgstr "串流 %{name} 成功儲存至 %{node}"
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
-#: src/views/certificate/CertificateEditor.vue:49
+#: src/views/certificate/components/CertificateEditor.vue:49
 #: src/views/preference/Preference.vue:124
 msgid "Save successfully"
 msgstr "儲存成功"
@@ -3146,7 +3202,7 @@ msgstr "sites-enabled 資料夾不存在"
 msgid "Skip Installation"
 msgstr "跳過安裝"
 
-#: src/views/certificate/CertificateEditor.vue:211
+#: src/views/certificate/components/CertificateEditor.vue:213
 msgid "SSL Certificate Content"
 msgstr "SSL 憑證內容"
 
@@ -3158,15 +3214,15 @@ msgstr "SSL憑證文件必須位於Nginx配置目錄下:{0}"
 msgid "SSL certificate file not found"
 msgstr "SSL憑證檔案未找到"
 
-#: src/views/certificate/CertificateEditor.vue:224
+#: src/views/certificate/components/CertificateEditor.vue:226
 msgid "SSL Certificate Key Content"
 msgstr "SSL 憑證金鑰內容"
 
-#: src/views/certificate/CertificateEditor.vue:190
+#: src/views/certificate/components/CertificateEditor.vue:192
 msgid "SSL Certificate Key Path"
 msgstr "SSL 憑證金鑰路徑"
 
-#: src/views/certificate/CertificateEditor.vue:175
+#: src/views/certificate/components/CertificateEditor.vue:177
 #: src/views/preference/ServerSettings.vue:36
 msgid "SSL Certificate Path"
 msgstr "SSL 憑證路徑"
@@ -3210,7 +3266,7 @@ msgstr "開始恢復"
 #: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/site/site_list/columns.tsx:80 src/views/stream/StreamList.vue:47
+#: src/views/site/site_list/columns.tsx:89 src/views/stream/StreamList.vue:47
 msgid "Status"
 msgstr "狀態"
 
@@ -3328,7 +3384,7 @@ msgstr "同步節點"
 msgid "Sync strategy"
 msgstr "同步策略"
 
-#: src/views/certificate/CertificateEditor.vue:204
+#: src/views/certificate/components/CertificateEditor.vue:206
 msgid "Sync to"
 msgstr "同步到"
 
@@ -3345,7 +3401,7 @@ msgstr "系統"
 msgid "System Backup"
 msgstr "系統備份"
 
-#: src/views/certificate/ACMEUserSelector.vue:88
+#: src/views/certificate/components/ACMEUserSelector.vue:88
 msgid "System Initial User"
 msgstr "系統初始使用者"
 
@@ -3393,11 +3449,11 @@ msgid ""
 "dashes, colons, and dots."
 msgstr "ICP 編號僅能包含字母、Unicode 字元、數字、連字號、破折號、冒號和句點。"
 
-#: src/views/certificate/CertificateEditor.vue:214
+#: src/views/certificate/components/CertificateEditor.vue:216
 msgid "The input is not a SSL Certificate"
 msgstr "輸入的不是 SSL 憑證"
 
-#: src/views/certificate/CertificateEditor.vue:227
+#: src/views/certificate/components/CertificateEditor.vue:229
 msgid "The input is not a SSL Certificate Key"
 msgstr "輸入的不是 SSL 憑證金鑰"
 
@@ -3422,11 +3478,11 @@ msgstr "節點名稱僅能包含字母、Unicode 字元、數字、連字號、
 msgid "The parameter of server_name is required"
 msgstr "必須提供 server_name 參數"
 
-#: src/views/certificate/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:181
 msgid "The path exists, but the file is not a certificate"
 msgstr "路徑存在,但檔案不是憑證"
 
-#: src/views/certificate/CertificateEditor.vue:194
+#: src/views/certificate/components/CertificateEditor.vue:196
 msgid "The path exists, but the file is not a private key"
 msgstr "路徑存在,但檔案不是金鑰"
 
@@ -3474,17 +3530,17 @@ msgstr ""
 "這些代碼是您在丟失密碼和第二重驗證因素時,訪問帳戶的最後手段。如果您找不到這"
 "些代碼,您將無法再訪問您的帳戶。"
 
-#: src/views/certificate/CertificateEditor.vue:102
+#: src/views/certificate/components/CertificateEditor.vue:102
 msgid "This Auto Cert item is invalid, please remove it."
 msgstr "此自動憑證項目無效,請將其移除。"
 
-#: src/views/certificate/CertificateEditor.vue:92
+#: src/views/certificate/components/CertificateEditor.vue:92
 msgid "This certificate is managed by Nginx UI"
 msgstr "此憑證由 Nginx UI 管理"
 
-#: src/views/certificate/CertificateEditor.vue:163
-#: src/views/certificate/CertificateEditor.vue:177
-#: src/views/certificate/CertificateEditor.vue:192
+#: src/views/certificate/components/CertificateEditor.vue:165
+#: src/views/certificate/components/CertificateEditor.vue:179
+#: src/views/certificate/components/CertificateEditor.vue:194
 msgid "This field is required"
 msgstr "此字段為必填項"
 
@@ -3506,6 +3562,12 @@ msgid ""
 "This field should only contain letters, unicode characters, numbers, and -_."
 msgstr "此欄位僅能包含字母、Unicode字元、數字、連字號、破折號和底線。"
 
+#: src/views/certificate/components/RemoveCert.vue:103
+msgid ""
+"This operation will only remove the certificate from the database. The "
+"certificate files on the file system will not be deleted."
+msgstr ""
+
 #: src/views/system/Backup/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -3549,6 +3611,10 @@ msgstr "提示"
 msgid "Title"
 msgstr "標題"
 
+#: src/views/certificate/components/RemoveCert.vue:121
+msgid "To confirm revocation, please type \"Revoke\" in the field below:"
+msgstr ""
+
 #: src/views/preference/components/TOTP.vue:68
 msgid ""
 "To enable it, you need to install the Google or Microsoft Authenticator app "
@@ -3632,7 +3698,7 @@ msgstr "更新成功"
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:75
-#: src/views/site/site_list/columns.tsx:110
+#: src/views/site/site_list/columns.tsx:82
 #: src/views/stream/components/RightSettings.vue:99
 #: src/views/stream/StreamList.vue:67 src/views/user/userColumns.tsx:54
 msgid "Updated at"
@@ -3757,7 +3823,8 @@ msgid ""
 "Warning: Restore operation will overwrite current configurations. Make sure "
 "you have a valid backup file and security token, and carefully select what "
 "to restore."
-msgstr "警告:恢復操作將覆蓋當前配置。請確保您擁有有效的備份檔案和安全令牌,並謹慎選"
+msgstr ""
+"警告:恢復操作將覆蓋當前配置。請確保您擁有有效的備份檔案和安全令牌,並謹慎選"
 "擇要恢復的內容。"
 
 #: src/views/certificate/DNSCredential.vue:56
@@ -3782,6 +3849,10 @@ msgstr "Webauthn"
 msgid "WebAuthn settings are not configured"
 msgstr "WebAuthn 設定尚未配置"
 
+#: src/views/certificate/components/RemoveCert.vue:54
+msgid "WebSocket connection error"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:83
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "
@@ -3795,14 +3866,16 @@ msgstr ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
-msgstr "當您啟用/停用、刪除或保存此網站時,在節點群組中設定的節點及下方選取的節點將同"
+msgstr ""
+"當您啟用/停用、刪除或保存此網站時,在節點群組中設定的節點及下方選取的節點將同"
 "步更新。"
 
 #: src/views/stream/components/RightSettings.vue:114
 msgid ""
 "When you enable/disable, delete, or save this stream, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
-msgstr "當您啟用/停用、刪除或儲存此串流時,在節點群組中設定的節點以及下方選取的節點將"
+msgstr ""
+"當您啟用/停用、刪除或儲存此串流時,在節點群組中設定的節點以及下方選取的節點將"
 "會同步更新。"
 
 #: src/views/preference/components/RecoveryCodes.vue:140

+ 2 - 2
app/src/routes/modules/certificates.ts

@@ -31,7 +31,7 @@ export const certificatesRoutes: RouteRecordRaw[] = [
       {
         path: ':id',
         name: 'Modify Certificate',
-        component: () => import('@/views/certificate/CertificateEditor.vue'),
+        component: () => import('@/views/certificate/components/CertificateEditor.vue'),
         meta: {
           name: () => $gettext('Modify Certificate'),
           hiddenInSidebar: true,
@@ -41,7 +41,7 @@ export const certificatesRoutes: RouteRecordRaw[] = [
       {
         path: 'import',
         name: 'Import Certificate',
-        component: () => import('@/views/certificate/CertificateEditor.vue'),
+        component: () => import('@/views/certificate/components/CertificateEditor.vue'),
         meta: {
           name: () => $gettext('Import Certificate'),
           hiddenInSidebar: true,

+ 13 - 2
app/src/views/certificate/CertificateList/Certificate.vue

@@ -1,8 +1,9 @@
 <script setup lang="tsx">
 import cert from '@/api/cert'
 import StdTable from '@/components/StdDesign/StdDataDisplay/StdTable.vue'
-import WildcardCertificate from '@/views/certificate/WildcardCertificate.vue'
 import { CloudUploadOutlined, SafetyCertificateOutlined } from '@ant-design/icons-vue'
+import RemoveCert from '../components/RemoveCert.vue'
+import WildcardCertificate from '../components/WildcardCertificate.vue'
 import certColumns from './certColumns'
 
 const refWildcard = ref()
@@ -14,6 +15,7 @@ const refTable = ref()
     <template #extra>
       <AButton
         type="link"
+        size="small"
         @click="$router.push('/certificates/import')"
       >
         <CloudUploadOutlined />
@@ -22,6 +24,7 @@ const refTable = ref()
 
       <AButton
         type="link"
+        size="small"
         @click="() => refWildcard.open()"
       >
         <SafetyCertificateOutlined />
@@ -34,8 +37,16 @@ const refTable = ref()
       :columns="certColumns"
       disable-view
       :scroll-x="1000"
+      disable-delete
       @click-edit="id => $router.push(`/certificates/${id}`)"
-    />
+    >
+      <template #actions="{ record }">
+        <RemoveCert
+          :id="record.id"
+          @removed="() => refTable.get_list()"
+        />
+      </template>
+    </StdTable>
     <WildcardCertificate
       ref="refWildcard"
       @issued="() => refTable.get_list()"

+ 0 - 0
app/src/views/certificate/ACMEUserSelector.vue → app/src/views/certificate/components/ACMEUserSelector.vue


+ 3 - 1
app/src/views/certificate/CertificateEditor.vue → app/src/views/certificate/components/CertificateEditor.vue

@@ -6,10 +6,10 @@ import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
 import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
 import NodeSelector from '@/components/NodeSelector/NodeSelector.vue'
 import { AutoCertState } from '@/constants'
-import RenewCert from '@/views/certificate/RenewCert.vue'
 import CertInfo from '@/views/site/cert/CertInfo.vue'
 import AutoCertStepOne from '@/views/site/cert/components/AutoCertStepOne.vue'
 import { message } from 'ant-design-vue'
+import RenewCert from './RenewCert.vue'
 
 const route = useRoute()
 
@@ -141,6 +141,8 @@ const isManaged = computed(() => {
               key_type: data.key_type,
               challenge_method: data.challenge_method,
               dns_credential_id: data.dns_credential_id,
+              acme_user_id: data.acme_user_id,
+              revoke_old: data.revoke_old,
             }"
             @renewed="init"
           />

+ 126 - 0
app/src/views/certificate/components/RemoveCert.vue

@@ -0,0 +1,126 @@
+<script setup lang="ts">
+import cert from '@/api/cert'
+import websocket from '@/lib/websocket'
+import { message } from 'ant-design-vue'
+
+const props = defineProps<{
+  id: number
+}>()
+
+const emit = defineEmits(['removed'])
+
+const modalVisible = ref(false)
+const confirmLoading = ref(false)
+const shouldRevoke = ref(false)
+const revokeInput = ref('')
+
+// Handle certificate deletion
+function handleDelete() {
+  // Open the combined modal directly
+  modalVisible.value = true
+}
+
+// Handle confirmation
+function handleConfirm() {
+  // If revocation is checked but confirmation text is not correct
+  if (shouldRevoke.value && revokeInput.value !== $gettext('Revoke')) {
+    message.error($gettext('Please type "Revoke" to confirm'))
+    return
+  }
+
+  confirmLoading.value = true
+
+  if (shouldRevoke.value) {
+    // Revoke certificate using WebSocket
+    const ws = websocket(`/api/certs/${props.id}/revoke`, false)
+
+    ws.onmessage = m => {
+      const response = JSON.parse(m.data)
+
+      if (response.status === 'success') {
+        message.success($gettext('Certificate removed successfully'))
+        // Close modal and refresh list
+        modalVisible.value = false
+        confirmLoading.value = false
+        emit('removed')
+      }
+      else if (response.status === 'error') {
+        message.error(response.message || $gettext('Failed to revoke certificate'))
+        confirmLoading.value = false
+      }
+    }
+
+    ws.onerror = () => {
+      message.error($gettext('WebSocket connection error'))
+      confirmLoading.value = false
+    }
+  }
+  else {
+    // Only remove certificate from database
+    cert.destroy(props.id).then(() => {
+      message.success($gettext('Certificate removed successfully'))
+      modalVisible.value = false
+      confirmLoading.value = false
+      emit('removed')
+    }).catch(error => {
+      message.error(error.message || $gettext('Failed to delete certificate'))
+      confirmLoading.value = false
+    })
+  }
+}
+
+// Handle modal cancel
+function handleCancel() {
+  modalVisible.value = false
+  shouldRevoke.value = false
+  revokeInput.value = ''
+}
+</script>
+
+<template>
+  <div class="inline-block">
+    <AButton
+      type="link"
+      size="small"
+      @click="handleDelete"
+    >
+      {{ $gettext('Delete') }}
+    </AButton>
+
+    <AModal
+      v-model:visible="modalVisible"
+      :title="$gettext('Delete Certificate')"
+      :confirm-loading="confirmLoading"
+      :ok-button-props="{
+        disabled: (shouldRevoke && revokeInput !== $gettext('Revoke')),
+      }"
+      @ok="handleConfirm"
+      @cancel="handleCancel"
+    >
+      <AAlert
+        type="warning"
+        show-icon
+        :message="$gettext('This operation will only remove the certificate from the database. The certificate files on the file system will not be deleted.')"
+        class="mb-4"
+      />
+
+      <div class="mb-4">
+        <ACheckbox v-model:checked="shouldRevoke">
+          {{ $gettext('Revoke this certificate') }}
+        </ACheckbox>
+      </div>
+
+      <div v-if="shouldRevoke">
+        <AAlert
+          type="error"
+          show-icon
+          :message="$gettext('Revoking a certificate will affect any services currently using it. This action cannot be undone.')"
+          class="mb-4"
+        />
+
+        <p>{{ $gettext('To confirm revocation, please type "Revoke" in the field below:') }}</p>
+        <AInput v-model:value="revokeInput" />
+      </div>
+    </AModal>
+  </div>
+</template>

+ 0 - 0
app/src/views/certificate/RenewCert.vue → app/src/views/certificate/components/RenewCert.vue


+ 0 - 0
app/src/views/certificate/WildcardCertificate.vue → app/src/views/certificate/components/WildcardCertificate.vue


+ 9 - 1
app/src/views/site/cert/components/AutoCertStepOne.vue

@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import type { AutoCertOptions } from '@/api/auto_cert'
 import { PrivateKeyTypeList } from '@/constants'
-import ACMEUserSelector from '@/views/certificate/ACMEUserSelector.vue'
+import ACMEUserSelector from '@/views/certificate/components/ACMEUserSelector.vue'
 import DNSChallenge from '@/views/site/cert/components/DNSChallenge.vue'
 
 const props = defineProps<{
@@ -111,6 +111,14 @@ watch(() => props.forceDnsChallenge, v => {
         </template>
         <ASwitch v-model:checked="data.lego_disable_cname_support" />
       </AFormItem>
+      <AFormItem :label="$gettext('Revoke Old Certificate')">
+        <template #help>
+          <p>
+            {{ $gettext('If you want to automatically revoke the old certificate, please enable this option.') }}
+          </p>
+        </template>
+        <ASwitch v-model:checked="data.revoke_old" />
+      </AFormItem>
     </AForm>
   </div>
 </template>

+ 1 - 0
internal/cert/auto_cert.go

@@ -79,6 +79,7 @@ func autoCert(certModel *model.Cert) {
 		NotBefore:               certInfo.NotBefore,
 		MustStaple:              certModel.MustStaple,
 		LegoDisableCNAMESupport: certModel.LegoDisableCNAMESupport,
+		RevokeOld:               certModel.RevokeOld,
 	}
 
 	if certModel.Resource != nil {

+ 34 - 0
internal/cert/cert.go → internal/cert/issue.go

@@ -8,6 +8,7 @@ import (
 	"github.com/0xJacky/Nginx-UI/internal/cert/dns"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/transport"
+	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/0xJacky/Nginx-UI/settings"
 	"github.com/go-acme/lego/v4/challenge/dns01"
@@ -162,6 +163,20 @@ func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error)
 		}()
 	}
 
+	// Backup current certificate and key if RevokeOld is true
+	var oldResource *model.CertificateResource
+
+	if payload.RevokeOld && payload.Resource != nil && payload.Resource.Certificate != nil {
+		l.Println("[INFO] [Nginx UI] Backing up current certificate for later revocation")
+
+		// Save a copy of the old certificate and key
+		oldResource = &model.CertificateResource{
+			Resource:    payload.Resource.Resource,
+			Certificate: payload.Resource.Certificate,
+			PrivateKey:  payload.Resource.PrivateKey,
+		}
+	}
+
 	if time.Now().Sub(payload.NotBefore).Hours()/24 <= 21 &&
 		payload.Resource != nil && payload.Resource.Certificate != nil {
 		renew(payload, client, l, errChan)
@@ -180,6 +195,25 @@ func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error)
 		ReloadServerTLSCertificate()
 	}
 
+	// Revoke old certificate if requested and we have a backup
+	if payload.RevokeOld && oldResource != nil && len(oldResource.Certificate) > 0 {
+		l.Println("[INFO] [Nginx UI] Revoking old certificate")
+
+		// Create a payload for revocation using old certificate
+		revokePayload := &ConfigPayload{
+			CertID:          payload.CertID,
+			ServerName:      payload.ServerName,
+			ChallengeMethod: payload.ChallengeMethod,
+			DNSCredentialID: payload.DNSCredentialID,
+			ACMEUserID:      payload.ACMEUserID,
+			KeyType:         payload.KeyType,
+			Resource:        oldResource,
+		}
+
+		// Revoke the old certificate
+		revoke(revokePayload, client, l, errChan)
+	}
+
 	// Wait log to be written
 	time.Sleep(2 * time.Second)
 }

+ 8 - 5
internal/cert/payload.go

@@ -1,6 +1,12 @@
 package cert
 
 import (
+	"log"
+	"os"
+	"path/filepath"
+	"strings"
+	"time"
+
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/model"
@@ -8,11 +14,6 @@ import (
 	"github.com/go-acme/lego/v4/certcrypto"
 	"github.com/pkg/errors"
 	"github.com/uozi-tech/cosy/logger"
-	"log"
-	"os"
-	"path/filepath"
-	"strings"
-	"time"
 )
 
 type ConfigPayload struct {
@@ -29,6 +30,7 @@ type ConfigPayload struct {
 	CertificateDir          string                     `json:"-"`
 	SSLCertificatePath      string                     `json:"-"`
 	SSLCertificateKeyPath   string                     `json:"-"`
+	RevokeOld               bool                       `json:"revoke_old"`
 }
 
 func (c *ConfigPayload) GetACMEUser() (user *model.AcmeUser, err error) {
@@ -110,6 +112,7 @@ func (c *ConfigPayload) WriteFile(l *log.Logger, errChan chan error) {
 	db.Where("id = ?", c.CertID).Updates(&model.Cert{
 		SSLCertificatePath:    c.GetCertificatePath(),
 		SSLCertificateKeyPath: c.GetCertificateKeyPath(),
+		Resource:              c.Resource,
 	})
 }
 

+ 105 - 0
internal/cert/revoke.go

@@ -0,0 +1,105 @@
+package cert
+
+import (
+	"log"
+	"os"
+	"time"
+
+	"github.com/0xJacky/Nginx-UI/internal/transport"
+	"github.com/go-acme/lego/v4/lego"
+	legolog "github.com/go-acme/lego/v4/log"
+	"github.com/pkg/errors"
+	"github.com/uozi-tech/cosy/logger"
+	cSettings "github.com/uozi-tech/cosy/settings"
+)
+
+// RevokeCert revokes a certificate and provides log messages through channels
+func RevokeCert(payload *ConfigPayload, logChan chan string, errChan chan error) {
+	defer func() {
+		if err := recover(); err != nil {
+			logger.Error(err)
+		}
+	}()
+
+	// Initialize a channel writer to receive logs
+	cw := NewChannelWriter()
+	defer close(errChan)
+	defer close(cw.Ch)
+
+	// Initialize a logger
+	l := log.New(os.Stderr, "", log.LstdFlags)
+	l.SetOutput(cw)
+
+	// Hijack the logger of lego
+	oldLogger := legolog.Logger
+	legolog.Logger = l
+	// Restore the original logger
+	defer func() {
+		legolog.Logger = oldLogger
+	}()
+
+	// Start a goroutine to fetch and process logs from channel
+	go func() {
+		for msg := range cw.Ch {
+			logChan <- string(msg)
+		}
+	}()
+
+	// Create client for communication with CA server
+	l.Println("[INFO] [Nginx UI] Preparing for certificate revocation")
+	user, err := payload.GetACMEUser()
+	if err != nil {
+		errChan <- errors.Wrap(err, "get ACME user error")
+		return
+	}
+
+	config := lego.NewConfig(user)
+	config.CADirURL = user.CADir
+
+	// Skip TLS check if proxy is configured
+	if config.HTTPClient != nil {
+		t, err := transport.NewTransport(
+			transport.WithProxy(user.Proxy))
+		if err != nil {
+			errChan <- errors.Wrap(err, "create transport error")
+			return
+		}
+		config.HTTPClient.Transport = t
+	}
+
+	config.Certificate.KeyType = payload.GetKeyType()
+
+	// Create the client
+	client, err := lego.NewClient(config)
+	if err != nil {
+		errChan <- errors.Wrap(err, "create client error")
+		return
+	}
+
+	revoke(payload, client, l, errChan)
+
+	// If the revoked certificate was used for the server itself, reload server TLS certificate
+	if payload.GetCertificatePath() == cSettings.ServerSettings.SSLCert &&
+		payload.GetCertificateKeyPath() == cSettings.ServerSettings.SSLKey {
+		l.Println("[INFO] [Nginx UI] Certificate was used for server, reloading server TLS certificate")
+		ReloadServerTLSCertificate()
+	}
+
+	l.Println("[INFO] [Nginx UI] Revocation completed")
+
+	// Wait for logs to be written
+	time.Sleep(2 * time.Second)
+}
+
+// revoke implements the internal certificate revocation logic
+func revoke(payload *ConfigPayload, client *lego.Client, l *log.Logger, errChan chan error) {
+	l.Println("[INFO] [Nginx UI] Revoking certificate")
+	err := client.Certificate.Revoke(payload.Resource.Certificate)
+	if err != nil {
+		errChan <- errors.Wrap(err, "revoke certificate error")
+		return 
+	}
+
+	l.Println("[INFO] [Nginx UI] Certificate successfully revoked")
+	return 
+}

+ 1 - 0
model/cert.go

@@ -48,6 +48,7 @@ type Cert struct {
 	SyncNodeIds             []uint64             `json:"sync_node_ids" gorm:"serializer:json"`
 	MustStaple              bool                 `json:"must_staple"`
 	LegoDisableCNAMESupport bool                 `json:"lego_disable_cname_support"`
+	RevokeOld               bool                 `json:"revoke_old"`
 }
 
 func FirstCert(confName string) (c Cert, err error) {

+ 5 - 1
query/certs.gen.go

@@ -47,6 +47,7 @@ func newCert(db *gorm.DB, opts ...gen.DOOption) cert {
 	_cert.SyncNodeIds = field.NewField(tableName, "sync_node_ids")
 	_cert.MustStaple = field.NewBool(tableName, "must_staple")
 	_cert.LegoDisableCNAMESupport = field.NewBool(tableName, "lego_disable_cname_support")
+	_cert.RevokeOld = field.NewBool(tableName, "revoke_old")
 	_cert.DnsCredential = certBelongsToDnsCredential{
 		db: db.Session(&gorm.Session{}),
 
@@ -87,6 +88,7 @@ type cert struct {
 	SyncNodeIds             field.Field
 	MustStaple              field.Bool
 	LegoDisableCNAMESupport field.Bool
+	RevokeOld               field.Bool
 	DnsCredential           certBelongsToDnsCredential
 
 	ACMEUser certBelongsToACMEUser
@@ -125,6 +127,7 @@ func (c *cert) updateTableName(table string) *cert {
 	c.SyncNodeIds = field.NewField(table, "sync_node_ids")
 	c.MustStaple = field.NewBool(table, "must_staple")
 	c.LegoDisableCNAMESupport = field.NewBool(table, "lego_disable_cname_support")
+	c.RevokeOld = field.NewBool(table, "revoke_old")
 
 	c.fillFieldMap()
 
@@ -141,7 +144,7 @@ func (c *cert) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
 }
 
 func (c *cert) fillFieldMap() {
-	c.fieldMap = make(map[string]field.Expr, 21)
+	c.fieldMap = make(map[string]field.Expr, 22)
 	c.fieldMap["id"] = c.ID
 	c.fieldMap["created_at"] = c.CreatedAt
 	c.fieldMap["updated_at"] = c.UpdatedAt
@@ -161,6 +164,7 @@ func (c *cert) fillFieldMap() {
 	c.fieldMap["sync_node_ids"] = c.SyncNodeIds
 	c.fieldMap["must_staple"] = c.MustStaple
 	c.fieldMap["lego_disable_cname_support"] = c.LegoDisableCNAMESupport
+	c.fieldMap["revoke_old"] = c.RevokeOld
 
 }