From 7d4999f83a9e258fd36a47d4683ab1f8b47ba80f Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Tue, 20 Dec 2022 18:07:07 +0800 Subject: [PATCH 01/22] wip: support SAN certifications --- frontend/src/views/domain/cert/IssueCert.vue | 31 +-- server/api/cert.go | 239 ++++++++++--------- server/pkg/cert/auto_cert.go | 2 +- server/pkg/cert/cert.go | 10 +- server/router/routers.go | 2 +- 5 files changed, 135 insertions(+), 149 deletions(-) diff --git a/frontend/src/views/domain/cert/IssueCert.vue b/frontend/src/views/domain/cert/IssueCert.vue index 93c38e85d..ffc2c7160 100644 --- a/frontend/src/views/domain/cert/IssueCert.vue +++ b/frontend/src/views/domain/cert/IssueCert.vue @@ -31,12 +31,6 @@ function job() { return } - if (server_name_more_than_one.value) { - message.error($gettext('server_name parameters more than one')) - issuing_cert.value = false - return - } - const server_name = props.directivesMap['server_name'][0] if (!props.directivesMap['ssl_certificate']) { @@ -102,10 +96,12 @@ const issue_cert = async (server_name: string, callback: Function) => { log($gettext('Getting the certificate, please wait...')) - const ws = websocket('/api/cert/issue/' + server_name, false) + const ws = websocket('/api/cert/issue', false) ws.onopen = () => { - ws.send('go') + ws.send(JSON.stringify({ + server_name: server_name.trim().split(' ') + })) } ws.onmessage = m => { @@ -132,11 +128,6 @@ const issue_cert = async (server_name: string, callback: Function) => { } } -const server_name_more_than_one = computed(() => { - return props.directivesMap['server_name'] && (props.directivesMap['server_name'].length > 1 || - props.directivesMap['server_name'][0].params.trim().indexOf(' ') > 0) -}) - const no_server_name = computed(() => { return props.directivesMap['server_name'].length === 0 }) @@ -154,11 +145,6 @@ const enabled = computed({ } }) -watch(server_name_more_than_one, () => { - emit('update:enabled', false) - onchange(false) -}) - watch(no_server_name, () => { emit('update:enabled', false) onchange(false) @@ -166,7 +152,7 @@ watch(no_server_name, () => { const progressStrokeColor = { from: '#108ee9', - to: '#87d068', + to: '#87d068' } const progressPercent = ref(0) @@ -197,10 +183,10 @@ const modalClosable = ref(false) :loading="issuing_cert" v-model:checked="enabled" @change="onchange" - :disabled="no_server_name||server_name_more_than_one" + :disabled="no_server_name" /> server_name parameter is required - - server_name parameters more than one - diff --git a/server/api/cert.go b/server/api/cert.go index 201c57ef5..7a7ad22fc 100644 --- a/server/api/cert.go +++ b/server/api/cert.go @@ -1,140 +1,141 @@ package api import ( - "github.com/0xJacky/Nginx-UI/server/model" - "github.com/0xJacky/Nginx-UI/server/pkg/cert" - "github.com/0xJacky/Nginx-UI/server/pkg/nginx" - "github.com/gin-gonic/gin" - "github.com/gorilla/websocket" - "log" - "net/http" + "github.com/0xJacky/Nginx-UI/server/model" + "github.com/0xJacky/Nginx-UI/server/pkg/cert" + "github.com/0xJacky/Nginx-UI/server/pkg/nginx" + "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" + "log" + "net/http" + "strings" ) const ( - Success = "success" - Info = "info" - Error = "error" + Success = "success" + Info = "info" + Error = "error" ) type IssueCertResponse struct { - Status string `json:"status"` - Message string `json:"message"` - SSLCertificate string `json:"ssl_certificate,omitempty"` - SSLCertificateKey string `json:"ssl_certificate_key,omitempty"` + Status string `json:"status"` + Message string `json:"message"` + SSLCertificate string `json:"ssl_certificate,omitempty"` + SSLCertificateKey string `json:"ssl_certificate_key,omitempty"` } func handleIssueCertLogChan(conn *websocket.Conn, logChan chan string) { - defer func() { - if err := recover(); err != nil { - log.Println("api.handleIssueCertLogChan recover", err) - } - }() + defer func() { + if err := recover(); err != nil { + log.Println("api.handleIssueCertLogChan recover", err) + } + }() - for logString := range logChan { + for logString := range logChan { - err := conn.WriteJSON(IssueCertResponse{ - Status: Info, - Message: logString, - }) + err := conn.WriteJSON(IssueCertResponse{ + Status: Info, + Message: logString, + }) - if err != nil { - log.Println("Error handleIssueCertLogChan", err) - return - } + if err != nil { + log.Println("Error handleIssueCertLogChan", err) + return + } - } + } } func IssueCert(c *gin.Context) { - domain := c.Param("domain") - - 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 { - log.Println(err) - return - } - - defer func(ws *websocket.Conn) { - err := ws.Close() - if err != nil { - log.Println("defer websocket close err", err) - } - }(ws) - - // read - mt, message, err := ws.ReadMessage() - - if err != nil { - log.Println(err) - return - } - - if mt != websocket.TextMessage || string(message) != "go" { - return - } - - logChan := make(chan string, 1) - errChan := make(chan error, 1) - - go cert.IssueCert(domain, logChan, errChan) - - go handleIssueCertLogChan(ws, logChan) - - // block, unless errChan closed - for err = range errChan { - log.Println("Error cert.IssueCert", err) - - err = ws.WriteJSON(IssueCertResponse{ - Status: Error, - Message: err.Error(), - }) - - if err != nil { - log.Println(err) - return - } - - return - } - - close(logChan) - - sslCertificatePath := nginx.GetNginxConfPath("ssl/" + domain + "/fullchain.cer") - sslCertificateKeyPath := nginx.GetNginxConfPath("ssl/" + domain + "/" + domain + ".key") - - certModel, err := model.FirstCert(domain) - - if err != nil { - log.Println(err) - return - } - - err = certModel.Updates(&model.Cert{ - SSLCertificatePath: sslCertificatePath, - }) - - if err != nil { - log.Println(err) - return - } - - err = ws.WriteJSON(IssueCertResponse{ - Status: Success, - Message: "Issued certificate successfully", - SSLCertificate: sslCertificatePath, - SSLCertificateKey: sslCertificateKeyPath, - }) - - if err != nil { - log.Println(err) - return - } + 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 { + log.Println(err) + return + } + + defer func(ws *websocket.Conn) { + err := ws.Close() + if err != nil { + log.Println("defer websocket close err", err) + } + }(ws) + + // read + var buffer struct { + ServerName []string `json:"server_name"` + } + + err = ws.ReadJSON(&buffer) + + if err != nil { + log.Println(err) + return + } + + logChan := make(chan string, 1) + errChan := make(chan error, 1) + + go cert.IssueCert(buffer.ServerName, logChan, errChan) + + domain := strings.Join(buffer.ServerName, "_") + + go handleIssueCertLogChan(ws, logChan) + + // block, unless errChan closed + for err = range errChan { + log.Println("Error cert.IssueCert", err) + + err = ws.WriteJSON(IssueCertResponse{ + Status: Error, + Message: err.Error(), + }) + + if err != nil { + log.Println(err) + return + } + + return + } + + close(logChan) + + sslCertificatePath := nginx.GetNginxConfPath("ssl/" + domain + "/fullchain.cer") + sslCertificateKeyPath := nginx.GetNginxConfPath("ssl/" + domain + "/" + domain + ".key") + + certModel, err := model.FirstCert(domain) + + if err != nil { + log.Println(err) + return + } + + err = certModel.Updates(&model.Cert{ + SSLCertificatePath: sslCertificatePath, + }) + + if err != nil { + log.Println(err) + return + } + + err = ws.WriteJSON(IssueCertResponse{ + Status: Success, + Message: "Issued certificate successfully", + SSLCertificate: sslCertificatePath, + SSLCertificateKey: sslCertificateKeyPath, + }) + + if err != nil { + log.Println(err) + return + } } diff --git a/server/pkg/cert/auto_cert.go b/server/pkg/cert/auto_cert.go index 0ba8a171f..97eeecf22 100644 --- a/server/pkg/cert/auto_cert.go +++ b/server/pkg/cert/auto_cert.go @@ -56,7 +56,7 @@ func AutoCert() { logChan := make(chan string, 1) errChan := make(chan error, 1) - go IssueCert(domain, logChan, errChan) + go IssueCert([]string{domain}, logChan, errChan) go handleIssueCertLogChan(logChan) diff --git a/server/pkg/cert/cert.go b/server/pkg/cert/cert.go index de2fbd5c8..cbdc99106 100644 --- a/server/pkg/cert/cert.go +++ b/server/pkg/cert/cert.go @@ -16,6 +16,7 @@ import ( "log" "os" "path/filepath" + "strings" ) // MyUser You'll need a user or account type that implements acme.User @@ -35,7 +36,7 @@ func (u *MyUser) GetPrivateKey() crypto.PrivateKey { return u.key } -func IssueCert(domain string, logChan chan string, errChan chan error) { +func IssueCert(domain []string, logChan chan string, errChan chan error) { defer func() { if err := recover(); err != nil { log.Println("Issue Cert recover", err) @@ -94,7 +95,7 @@ func IssueCert(domain string, logChan chan string, errChan chan error) { myUser.Registration = reg request := certificate.ObtainRequest{ - Domains: []string{domain}, + Domains: domain, Bundle: true, } @@ -104,7 +105,8 @@ func IssueCert(domain string, logChan chan string, errChan chan error) { errChan <- errors.Wrap(err, "issue cert fail to obtain") return } - saveDir := nginx.GetNginxConfPath("ssl/" + domain) + name := strings.Join(domain, "_") + saveDir := nginx.GetNginxConfPath("ssl/" + name) if _, err = os.Stat(saveDir); os.IsNotExist(err) { err = os.MkdirAll(saveDir, 0755) if err != nil { @@ -125,7 +127,7 @@ func IssueCert(domain string, logChan chan string, errChan chan error) { } logChan <- "Writing certificate private key to disk" - err = os.WriteFile(filepath.Join(saveDir, domain+".key"), + err = os.WriteFile(filepath.Join(saveDir, name+".key"), certificates.PrivateKey, 0644) if err != nil { diff --git a/server/router/routers.go b/server/router/routers.go index f44fd8862..7be562112 100644 --- a/server/router/routers.go +++ b/server/router/routers.go @@ -83,7 +83,7 @@ func InitRouter() *gin.Engine { g.GET("template", api.GetTemplate) - g.GET("cert/issue/:domain", api.IssueCert) + g.GET("cert/issue", api.IssueCert) // Add domain to auto-renew cert list g.POST("cert/:domain", api.AddDomainToAutoCert) From f6a5f350ad2ba4ba1fe66640e985f009e1b32743 Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Sun, 25 Dec 2022 23:31:23 +0800 Subject: [PATCH 02/22] wip: modify config file name --- frontend/src/views/domain/DomainEdit.vue | 19 +- server/api/domain.go | 602 ++++++++++++----------- 2 files changed, 339 insertions(+), 282 deletions(-) diff --git a/frontend/src/views/domain/DomainEdit.vue b/frontend/src/views/domain/DomainEdit.vue index 4ed9622b3..840f2bfc9 100644 --- a/frontend/src/views/domain/DomainEdit.vue +++ b/frontend/src/views/domain/DomainEdit.vue @@ -4,8 +4,8 @@ import CodeEditor from '@/components/CodeEditor/CodeEditor.vue' import NgxConfigEditor from '@/views/domain/ngx_conf/NgxConfigEditor' import {useGettext} from 'vue3-gettext' -import {reactive, ref} from 'vue' -import {useRoute} from 'vue-router' +import {reactive, ref, watch} from 'vue' +import {useRoute, useRouter} from 'vue-router' import domain from '@/api/domain' import ngx from '@/api/ngx' import {message} from 'ant-design-vue' @@ -14,8 +14,13 @@ import {message} from 'ant-design-vue' const {$gettext, interpolate} = useGettext() const route = useRoute() +const router = useRouter() const name = ref(route.params.name.toString()) +watch(route, () => { + name.value = route.params.name.toString() +}) + const update = ref(0) const ngx_config = reactive({ @@ -32,6 +37,7 @@ const configText = ref('') const ok = ref(false) const advance_mode = ref(false) const saving = ref(false) +const filename = ref('') init() @@ -40,7 +46,7 @@ function handle_response(r: any) { Object.keys(cert_info_map).forEach(v => { delete cert_info_map[v] }) - + filename.value = r.name configText.value = r.config enabled.value = r.enabled auto_cert.value = r.auto_cert @@ -85,9 +91,9 @@ const save = async () => { await build_config() } - domain.save(name.value, {content: configText.value}).then(r => { + domain.save(name.value, {name: filename.value, content: configText.value}).then(r => { handle_response(r) - + router.push('/domain/' + filename.value) message.success($gettext('Saved successfully')) }).catch((e: any) => { @@ -159,6 +165,9 @@ function on_change_enabled(checked: boolean) { + + + Date: Sun, 1 Jan 2023 11:18:21 +0800 Subject: [PATCH 03/22] fix: Auto correcting code is broken in advance mode #50 --- frontend/src/views/domain/DomainEdit.vue | 2 +- server/pkg/nginx/tokenize.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/views/domain/DomainEdit.vue b/frontend/src/views/domain/DomainEdit.vue index 840f2bfc9..5f70ef9c8 100644 --- a/frontend/src/views/domain/DomainEdit.vue +++ b/frontend/src/views/domain/DomainEdit.vue @@ -18,7 +18,7 @@ const router = useRouter() const name = ref(route.params.name.toString()) watch(route, () => { - name.value = route.params.name.toString() + name.value = route.params?.name?.toString() ?? '' }) const update = ref(0) diff --git a/server/pkg/nginx/tokenize.go b/server/pkg/nginx/tokenize.go index e8a634233..02ed34c90 100644 --- a/server/pkg/nginx/tokenize.go +++ b/server/pkg/nginx/tokenize.go @@ -76,7 +76,7 @@ func (s *NgxServer) parseDirective(d NgxDirective) { return } - regExp := regexp.MustCompile("(\\S+?)\\s+?{?(.+?)[;|}]") + regExp := regexp.MustCompile("(\\S+?)\\s+?{?(.+)[;|}]") matchSlice := regExp.FindAllStringSubmatch(str, -1) for k, v := range matchSlice { From 42d832cd9f865951eee43f581e6d643e4abc9b0a Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Sun, 1 Jan 2023 13:13:35 +0800 Subject: [PATCH 04/22] feat: support SAN certification #49 --- server/api/cert.go | 238 +++++++------ server/api/domain.go | 631 ++++++++++++++++++----------------- server/pkg/cert/auto_cert.go | 4 +- server/pkg/cert/cert.go | 4 +- 4 files changed, 442 insertions(+), 435 deletions(-) diff --git a/server/api/cert.go b/server/api/cert.go index 7a7ad22fc..58a59d497 100644 --- a/server/api/cert.go +++ b/server/api/cert.go @@ -1,141 +1,139 @@ package api import ( - "github.com/0xJacky/Nginx-UI/server/model" - "github.com/0xJacky/Nginx-UI/server/pkg/cert" - "github.com/0xJacky/Nginx-UI/server/pkg/nginx" - "github.com/gin-gonic/gin" - "github.com/gorilla/websocket" - "log" - "net/http" - "strings" + "github.com/0xJacky/Nginx-UI/server/model" + "github.com/0xJacky/Nginx-UI/server/pkg/cert" + "github.com/0xJacky/Nginx-UI/server/pkg/nginx" + "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" + "log" + "net/http" + "strings" ) const ( - Success = "success" - Info = "info" - Error = "error" + Success = "success" + Info = "info" + Error = "error" ) type IssueCertResponse struct { - Status string `json:"status"` - Message string `json:"message"` - SSLCertificate string `json:"ssl_certificate,omitempty"` - SSLCertificateKey string `json:"ssl_certificate_key,omitempty"` + Status string `json:"status"` + Message string `json:"message"` + SSLCertificate string `json:"ssl_certificate,omitempty"` + SSLCertificateKey string `json:"ssl_certificate_key,omitempty"` } func handleIssueCertLogChan(conn *websocket.Conn, logChan chan string) { - defer func() { - if err := recover(); err != nil { - log.Println("api.handleIssueCertLogChan recover", err) - } - }() + defer func() { + if err := recover(); err != nil { + log.Println("api.handleIssueCertLogChan recover", err) + } + }() - for logString := range logChan { + for logString := range logChan { - err := conn.WriteJSON(IssueCertResponse{ - Status: Info, - Message: logString, - }) + err := conn.WriteJSON(IssueCertResponse{ + Status: Info, + Message: logString, + }) - if err != nil { - log.Println("Error handleIssueCertLogChan", err) - return - } + if err != nil { + log.Println("Error handleIssueCertLogChan", err) + return + } - } + } } func IssueCert(c *gin.Context) { - 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 { - log.Println(err) - return - } - - defer func(ws *websocket.Conn) { - err := ws.Close() - if err != nil { - log.Println("defer websocket close err", err) - } - }(ws) - - // read - var buffer struct { - ServerName []string `json:"server_name"` - } - - err = ws.ReadJSON(&buffer) - - if err != nil { - log.Println(err) - return - } - - logChan := make(chan string, 1) - errChan := make(chan error, 1) - - go cert.IssueCert(buffer.ServerName, logChan, errChan) - - domain := strings.Join(buffer.ServerName, "_") - - go handleIssueCertLogChan(ws, logChan) - - // block, unless errChan closed - for err = range errChan { - log.Println("Error cert.IssueCert", err) - - err = ws.WriteJSON(IssueCertResponse{ - Status: Error, - Message: err.Error(), - }) - - if err != nil { - log.Println(err) - return - } - - return - } - - close(logChan) - - sslCertificatePath := nginx.GetNginxConfPath("ssl/" + domain + "/fullchain.cer") - sslCertificateKeyPath := nginx.GetNginxConfPath("ssl/" + domain + "/" + domain + ".key") - - certModel, err := model.FirstCert(domain) - - if err != nil { - log.Println(err) - return - } - - err = certModel.Updates(&model.Cert{ - SSLCertificatePath: sslCertificatePath, - }) - - if err != nil { - log.Println(err) - return - } - - err = ws.WriteJSON(IssueCertResponse{ - Status: Success, - Message: "Issued certificate successfully", - SSLCertificate: sslCertificatePath, - SSLCertificateKey: sslCertificateKeyPath, - }) - - if err != nil { - log.Println(err) - return - } + 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 { + log.Println(err) + return + } + + defer func(ws *websocket.Conn) { + err := ws.Close() + if err != nil { + log.Println("defer websocket close err", err) + } + }(ws) + + // read + var buffer struct { + ServerName []string `json:"server_name"` + } + + err = ws.ReadJSON(&buffer) + + if err != nil { + log.Println(err) + return + } + + logChan := make(chan string, 1) + errChan := make(chan error, 1) + + go cert.IssueCert(buffer.ServerName, logChan, errChan) + + domain := strings.Join(buffer.ServerName, "_") + + go handleIssueCertLogChan(ws, logChan) + + // block, unless errChan closed + for err = range errChan { + log.Println("Error cert.IssueCert", err) + + err = ws.WriteJSON(IssueCertResponse{ + Status: Error, + Message: err.Error(), + }) + + if err != nil { + log.Println("Error WriteJSON", err) + return + } + + return + } + + close(logChan) + + sslCertificatePath := nginx.GetNginxConfPath("ssl/" + domain + "/fullchain.cer") + sslCertificateKeyPath := nginx.GetNginxConfPath("ssl/" + domain + "/private.key") + + certModel, err := model.FirstOrCreateCert(domain) + + if err != nil { + log.Println(err) + } + + err = certModel.Updates(&model.Cert{ + SSLCertificatePath: sslCertificatePath, + }) + + if err != nil { + log.Println(err) + } + + err = ws.WriteJSON(IssueCertResponse{ + Status: Success, + Message: "Issued certificate successfully", + SSLCertificate: sslCertificatePath, + SSLCertificateKey: sslCertificateKeyPath, + }) + + if err != nil { + log.Println(err) + return + } } diff --git a/server/api/domain.go b/server/api/domain.go index 636adfc45..00d5161cc 100644 --- a/server/api/domain.go +++ b/server/api/domain.go @@ -1,358 +1,365 @@ package api import ( - "github.com/0xJacky/Nginx-UI/server/model" - "github.com/0xJacky/Nginx-UI/server/pkg/cert" - "github.com/0xJacky/Nginx-UI/server/pkg/config_list" - "github.com/0xJacky/Nginx-UI/server/pkg/nginx" - "github.com/gin-gonic/gin" - "log" - "net/http" - "os" - "path/filepath" - "strings" - "time" + "github.com/0xJacky/Nginx-UI/server/model" + "github.com/0xJacky/Nginx-UI/server/pkg/cert" + "github.com/0xJacky/Nginx-UI/server/pkg/config_list" + "github.com/0xJacky/Nginx-UI/server/pkg/nginx" + "github.com/gin-gonic/gin" + "log" + "net/http" + "os" + "path/filepath" + "strings" + "time" ) func GetDomains(c *gin.Context) { - name := c.Query("name") - orderBy := c.Query("order_by") - sort := c.DefaultQuery("sort", "desc") - - mySort := map[string]string{ - "enabled": "bool", - "name": "string", - "modify": "time", - } - - configFiles, err := os.ReadDir(nginx.GetNginxConfPath("sites-available")) - - if err != nil { - ErrHandler(c, err) - return - } - - enabledConfig, err := os.ReadDir(filepath.Join(nginx.GetNginxConfPath("sites-enabled"))) - - if err != nil { - ErrHandler(c, err) - return - } - - enabledConfigMap := make(map[string]bool) - for i := range enabledConfig { - enabledConfigMap[enabledConfig[i].Name()] = true - } - - var configs []gin.H - - for i := range configFiles { - file := configFiles[i] - fileInfo, _ := file.Info() - if !file.IsDir() { - if name != "" && !strings.Contains(file.Name(), name) { - continue - } - configs = append(configs, gin.H{ - "name": file.Name(), - "size": fileInfo.Size(), - "modify": fileInfo.ModTime(), - "enabled": enabledConfigMap[file.Name()], - }) - } - } - - configs = config_list.Sort(orderBy, sort, mySort[orderBy], configs) - - c.JSON(http.StatusOK, gin.H{ - "data": configs, - }) + name := c.Query("name") + orderBy := c.Query("order_by") + sort := c.DefaultQuery("sort", "desc") + + mySort := map[string]string{ + "enabled": "bool", + "name": "string", + "modify": "time", + } + + configFiles, err := os.ReadDir(nginx.GetNginxConfPath("sites-available")) + + if err != nil { + ErrHandler(c, err) + return + } + + enabledConfig, err := os.ReadDir(filepath.Join(nginx.GetNginxConfPath("sites-enabled"))) + + if err != nil { + ErrHandler(c, err) + return + } + + enabledConfigMap := make(map[string]bool) + for i := range enabledConfig { + enabledConfigMap[enabledConfig[i].Name()] = true + } + + var configs []gin.H + + for i := range configFiles { + file := configFiles[i] + fileInfo, _ := file.Info() + if !file.IsDir() { + if name != "" && !strings.Contains(file.Name(), name) { + continue + } + configs = append(configs, gin.H{ + "name": file.Name(), + "size": fileInfo.Size(), + "modify": fileInfo.ModTime(), + "enabled": enabledConfigMap[file.Name()], + }) + } + } + + configs = config_list.Sort(orderBy, sort, mySort[orderBy], configs) + + c.JSON(http.StatusOK, gin.H{ + "data": configs, + }) } type CertificateInfo struct { - SubjectName string `json:"subject_name"` - IssuerName string `json:"issuer_name"` - NotAfter time.Time `json:"not_after"` - NotBefore time.Time `json:"not_before"` + SubjectName string `json:"subject_name"` + IssuerName string `json:"issuer_name"` + NotAfter time.Time `json:"not_after"` + NotBefore time.Time `json:"not_before"` } func GetDomain(c *gin.Context) { - rewriteName, ok := c.Get("rewriteConfigFileName") + rewriteName, ok := c.Get("rewriteConfigFileName") - name := c.Param("name") + name := c.Param("name") - // for modify filename - if ok { - name = rewriteName.(string) - } + // for modify filename + if ok { + name = rewriteName.(string) + } - path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) + path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) - enabled := true - if _, err := os.Stat(filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name)); os.IsNotExist(err) { - enabled = false - } + enabled := true + if _, err := os.Stat(filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name)); os.IsNotExist(err) { + enabled = false + } - config, err := nginx.ParseNgxConfig(path) + config, err := nginx.ParseNgxConfig(path) - if err != nil { - ErrHandler(c, err) - return - } + if err != nil { + ErrHandler(c, err) + return + } - certInfoMap := make(map[int]CertificateInfo) - for serverIdx, server := range config.Servers { - for _, directive := range server.Directives { - if directive.Directive == "ssl_certificate" { + certInfoMap := make(map[int]CertificateInfo) + var serverName string + for serverIdx, server := range config.Servers { + for _, directive := range server.Directives { - pubKey, err := cert.GetCertInfo(directive.Params) + if directive.Directive == "server_name" { + serverName = strings.ReplaceAll(directive.Params, " ", "_") + continue + } - if err != nil { - log.Println("Failed to get certificate information", err) - break - } + if directive.Directive == "ssl_certificate" { - certInfoMap[serverIdx] = CertificateInfo{ - SubjectName: pubKey.Subject.CommonName, - IssuerName: pubKey.Issuer.CommonName, - NotAfter: pubKey.NotAfter, - NotBefore: pubKey.NotBefore, - } + pubKey, err := cert.GetCertInfo(directive.Params) - break - } - } - } + if err != nil { + log.Println("Failed to get certificate information", err) + break + } - _, err = model.FirstCert(name) + certInfoMap[serverIdx] = CertificateInfo{ + SubjectName: pubKey.Subject.CommonName, + IssuerName: pubKey.Issuer.CommonName, + NotAfter: pubKey.NotAfter, + NotBefore: pubKey.NotBefore, + } - c.JSON(http.StatusOK, gin.H{ - "enabled": enabled, - "name": name, - "config": config.BuildConfig(), - "tokenized": config, - "auto_cert": err == nil, - "cert_info": certInfoMap, - }) + break + } + } + } + + _, err = model.FirstCert(serverName) + + c.JSON(http.StatusOK, gin.H{ + "enabled": enabled, + "name": name, + "config": config.BuildConfig(), + "tokenized": config, + "auto_cert": err == nil, + "cert_info": certInfoMap, + }) } func EditDomain(c *gin.Context) { - name := c.Param("name") - - if name == "" { - c.JSON(http.StatusNotAcceptable, gin.H{ - "message": "param name is empty", - }) - return - } - - var json struct { - Name string `json:"name" binding:"required"` - Content string `json:"content"` - } - - if !BindAndValid(c, &json) { - return - } - - path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) - - err := os.WriteFile(path, []byte(json.Content), 0644) - if err != nil { - ErrHandler(c, err) - return - } - enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name) - // rename the config file if needed - if name != json.Name { - newPath := filepath.Join(nginx.GetNginxConfPath("sites-available"), json.Name) - // recreate soft link - log.Println(enabledConfigFilePath) - if _, err = os.Stat(enabledConfigFilePath); err == nil { - log.Println(enabledConfigFilePath) - _ = os.Remove(enabledConfigFilePath) - enabledConfigFilePath = filepath.Join(nginx.GetNginxConfPath("sites-enabled"), json.Name) - err = os.Symlink(newPath, enabledConfigFilePath) - - if err != nil { - ErrHandler(c, err) - return - } - } - err = os.Rename(path, newPath) - if err != nil { - ErrHandler(c, err) - return - } - name = json.Name - c.Set("rewriteConfigFileName", name) - - } - - enabledConfigFilePath = filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name) - if _, err = os.Stat(enabledConfigFilePath); err == nil { - // Test nginx configuration - err = nginx.TestNginxConf() - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": err.Error(), - }) - return - } - - output := nginx.ReloadNginx() - - if output != "" && strings.Contains(output, "error") { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": output, - }) - return - } - } - - GetDomain(c) + name := c.Param("name") + + if name == "" { + c.JSON(http.StatusNotAcceptable, gin.H{ + "message": "param name is empty", + }) + return + } + + var json struct { + Name string `json:"name" binding:"required"` + Content string `json:"content"` + } + + if !BindAndValid(c, &json) { + return + } + + path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) + + err := os.WriteFile(path, []byte(json.Content), 0644) + if err != nil { + ErrHandler(c, err) + return + } + enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name) + // rename the config file if needed + if name != json.Name { + newPath := filepath.Join(nginx.GetNginxConfPath("sites-available"), json.Name) + // recreate soft link + log.Println(enabledConfigFilePath) + if _, err = os.Stat(enabledConfigFilePath); err == nil { + log.Println(enabledConfigFilePath) + _ = os.Remove(enabledConfigFilePath) + enabledConfigFilePath = filepath.Join(nginx.GetNginxConfPath("sites-enabled"), json.Name) + err = os.Symlink(newPath, enabledConfigFilePath) + + if err != nil { + ErrHandler(c, err) + return + } + } + err = os.Rename(path, newPath) + if err != nil { + ErrHandler(c, err) + return + } + name = json.Name + c.Set("rewriteConfigFileName", name) + + } + + enabledConfigFilePath = filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name) + if _, err = os.Stat(enabledConfigFilePath); err == nil { + // Test nginx configuration + err = nginx.TestNginxConf() + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": err.Error(), + }) + return + } + + output := nginx.ReloadNginx() + + if output != "" && strings.Contains(output, "error") { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": output, + }) + return + } + } + + GetDomain(c) } func EnableDomain(c *gin.Context) { - configFilePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), c.Param("name")) - enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name")) - - _, err := os.Stat(configFilePath) - - if err != nil { - ErrHandler(c, err) - return - } - - if _, err = os.Stat(enabledConfigFilePath); os.IsNotExist(err) { - err = os.Symlink(configFilePath, enabledConfigFilePath) - - if err != nil { - ErrHandler(c, err) - return - } - } - - // Test nginx config, if not pass then rollback. - err = nginx.TestNginxConf() - if err != nil { - _ = os.Remove(enabledConfigFilePath) - c.JSON(http.StatusInternalServerError, gin.H{ - "message": err.Error(), - }) - return - } - - output := nginx.ReloadNginx() - - if output != "" && strings.Contains(output, "error") { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": output, - }) - return - } - - c.JSON(http.StatusOK, gin.H{ - "message": "ok", - }) + configFilePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), c.Param("name")) + enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name")) + + _, err := os.Stat(configFilePath) + + if err != nil { + ErrHandler(c, err) + return + } + + if _, err = os.Stat(enabledConfigFilePath); os.IsNotExist(err) { + err = os.Symlink(configFilePath, enabledConfigFilePath) + + if err != nil { + ErrHandler(c, err) + return + } + } + + // Test nginx config, if not pass then rollback. + err = nginx.TestNginxConf() + if err != nil { + _ = os.Remove(enabledConfigFilePath) + c.JSON(http.StatusInternalServerError, gin.H{ + "message": err.Error(), + }) + return + } + + output := nginx.ReloadNginx() + + if output != "" && strings.Contains(output, "error") { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": output, + }) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) } func DisableDomain(c *gin.Context) { - enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name")) - - _, err := os.Stat(enabledConfigFilePath) - - if err != nil { - ErrHandler(c, err) - return - } - - err = os.Remove(enabledConfigFilePath) - - if err != nil { - ErrHandler(c, err) - return - } - - // delete auto cert record - certModel := model.Cert{Domain: c.Param("name")} - err = certModel.Remove() - if err != nil { - ErrHandler(c, err) - return - } - - output := nginx.ReloadNginx() - - if output != "" { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": output, - }) - return - } - - c.JSON(http.StatusOK, gin.H{ - "message": "ok", - }) + enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name")) + + _, err := os.Stat(enabledConfigFilePath) + + if err != nil { + ErrHandler(c, err) + return + } + + err = os.Remove(enabledConfigFilePath) + + if err != nil { + ErrHandler(c, err) + return + } + + // delete auto cert record + certModel := model.Cert{Domain: c.Param("name")} + err = certModel.Remove() + if err != nil { + ErrHandler(c, err) + return + } + + output := nginx.ReloadNginx() + + if output != "" { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": output, + }) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) } func DeleteDomain(c *gin.Context) { - var err error - name := c.Param("name") - availablePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) - enabledPath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name) - - if _, err = os.Stat(availablePath); os.IsNotExist(err) { - c.JSON(http.StatusNotFound, gin.H{ - "message": "site not found", - }) - return - } - - if _, err = os.Stat(enabledPath); err == nil { - c.JSON(http.StatusNotAcceptable, gin.H{ - "message": "site is enabled", - }) - return - } - - certModel := model.Cert{Domain: name} - _ = certModel.Remove() - - err = os.Remove(availablePath) - - if err != nil { - ErrHandler(c, err) - return - } - - c.JSON(http.StatusOK, gin.H{ - "message": "ok", - }) + var err error + name := c.Param("name") + availablePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) + enabledPath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name) + + if _, err = os.Stat(availablePath); os.IsNotExist(err) { + c.JSON(http.StatusNotFound, gin.H{ + "message": "site not found", + }) + return + } + + if _, err = os.Stat(enabledPath); err == nil { + c.JSON(http.StatusNotAcceptable, gin.H{ + "message": "site is enabled", + }) + return + } + + certModel := model.Cert{Domain: name} + _ = certModel.Remove() + + err = os.Remove(availablePath) + + if err != nil { + ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) } func AddDomainToAutoCert(c *gin.Context) { - domain := c.Param("domain") - - certModel, err := model.FirstOrCreateCert(domain) - if err != nil { - ErrHandler(c, err) - return - } - c.JSON(http.StatusOK, certModel) + domain := c.Param("domain") + + certModel, err := model.FirstOrCreateCert(domain) + if err != nil { + ErrHandler(c, err) + return + } + c.JSON(http.StatusOK, certModel) } func RemoveDomainFromAutoCert(c *gin.Context) { - certModel := model.Cert{ - Domain: c.Param("domain"), - } - err := certModel.Remove() - - if err != nil { - ErrHandler(c, err) - return - } - c.JSON(http.StatusOK, nil) + certModel := model.Cert{ + Domain: c.Param("domain"), + } + err := certModel.Remove() + + if err != nil { + ErrHandler(c, err) + return + } + c.JSON(http.StatusOK, nil) } diff --git a/server/pkg/cert/auto_cert.go b/server/pkg/cert/auto_cert.go index 97eeecf22..9d5e08044 100644 --- a/server/pkg/cert/auto_cert.go +++ b/server/pkg/cert/auto_cert.go @@ -3,6 +3,7 @@ package cert import ( "github.com/0xJacky/Nginx-UI/server/model" "log" + "strings" "time" ) @@ -56,7 +57,8 @@ func AutoCert() { logChan := make(chan string, 1) errChan := make(chan error, 1) - go IssueCert([]string{domain}, logChan, errChan) + // support SAN certification + go IssueCert(strings.Split(domain, "_"), logChan, errChan) go handleIssueCertLogChan(logChan) diff --git a/server/pkg/cert/cert.go b/server/pkg/cert/cert.go index cbdc99106..710c5b991 100644 --- a/server/pkg/cert/cert.go +++ b/server/pkg/cert/cert.go @@ -105,7 +105,7 @@ func IssueCert(domain []string, logChan chan string, errChan chan error) { errChan <- errors.Wrap(err, "issue cert fail to obtain") return } - name := strings.Join(domain, "_") + name := strings.Join(domain, " ") saveDir := nginx.GetNginxConfPath("ssl/" + name) if _, err = os.Stat(saveDir); os.IsNotExist(err) { err = os.MkdirAll(saveDir, 0755) @@ -127,7 +127,7 @@ func IssueCert(domain []string, logChan chan string, errChan chan error) { } logChan <- "Writing certificate private key to disk" - err = os.WriteFile(filepath.Join(saveDir, name+".key"), + err = os.WriteFile(filepath.Join(saveDir, "private.key"), certificates.PrivateKey, 0644) if err != nil { From bc247ffd23f28f10611b96e2031903ae8d3d7565 Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Sun, 1 Jan 2023 14:34:31 +0800 Subject: [PATCH 05/22] wip: force theme #40 --- frontend/package.json | 2 +- frontend/src/App.vue | 17 +- .../FooterToolbar/FooterToolBar.vue | 11 +- frontend/src/components/Logo/Logo.vue | 13 +- .../src/components/PageHeader/PageHeader.vue | 13 +- .../StdDataEntry/components/StdSelector.vue | 47 ++- .../StdDataEntry/compontents/StdSelector.vue | 52 +-- frontend/src/language/en/app.po | 260 ++++++++----- frontend/src/language/messages.pot | 265 ++++++++----- frontend/src/language/translations.json | 2 +- frontend/src/language/zh_CN/app.mo | Bin 9227 -> 9553 bytes frontend/src/language/zh_CN/app.po | 264 ++++++++----- frontend/src/language/zh_TW/app.mo | Bin 0 -> 9646 bytes frontend/src/language/zh_TW/app.po | 349 ++++++++++-------- frontend/src/layouts/BaseLayout.vue | 58 +-- frontend/src/layouts/HeaderLayout.vue | 2 +- frontend/src/lib/theme/index.ts | 1 + frontend/src/pinia/moudule/settings.ts | 4 + frontend/src/routes/index.ts | 31 +- frontend/src/version.json | 2 +- frontend/src/views/domain/DomainList.vue | 2 +- frontend/src/views/preference/Preference.vue | 58 +++ frontend/version.json | 2 +- 23 files changed, 891 insertions(+), 564 deletions(-) create mode 100644 frontend/src/language/zh_TW/app.mo create mode 100644 frontend/src/views/preference/Preference.vue diff --git a/frontend/package.json b/frontend/package.json index 12b212053..59d3c5f28 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "nginx-ui-frontend-next", "private": true, - "version": "1.6.8", + "version": "1.7.0", "type": "commonjs", "scripts": { "dev": "vite", diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 77d2df86b..dcdbb1b3c 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -5,17 +5,22 @@ import {useSettingsStore} from '@/pinia' import {dark_mode} from '@/lib/theme' let media = window.matchMedia('(prefers-color-scheme: dark)') + const callback = (media: { matches: any; }) => { const settings = useSettingsStore() - if (media.matches) { - dark_mode(true) - settings.set_theme('dark') - } else { - dark_mode(false) - settings.set_theme('default') + if (settings.preference_theme === 'auto') { + if (media.matches) { + dark_mode(true) + settings.set_theme('dark') + } else { + dark_mode(false) + settings.set_theme('auto') + } } } + callback(media) + if (typeof media.addEventListener === 'function') { media.addEventListener('change', callback) } else if (typeof media.addListener === 'function') { diff --git a/frontend/src/components/FooterToolbar/FooterToolBar.vue b/frontend/src/components/FooterToolbar/FooterToolBar.vue index 3a3fd6243..b952b64f4 100644 --- a/frontend/src/components/FooterToolbar/FooterToolBar.vue +++ b/frontend/src/components/FooterToolbar/FooterToolBar.vue @@ -26,6 +26,13 @@ export default { \ No newline at end of file + diff --git a/frontend/src/components/StdDataEntry/compontents/StdSelector.vue b/frontend/src/components/StdDataEntry/compontents/StdSelector.vue index 8625995b9..efa662f7c 100644 --- a/frontend/src/components/StdDataEntry/compontents/StdSelector.vue +++ b/frontend/src/components/StdDataEntry/compontents/StdSelector.vue @@ -70,28 +70,28 @@ watch(props, () => { {{ M_value }} {{ description }} @@ -99,6 +99,12 @@ watch(props, () => { \ No newline at end of file + diff --git a/frontend/src/language/en/app.po b/frontend/src/language/en/app.po index 00f363a7c..be27c8d57 100644 --- a/frontend/src/language/en/app.po +++ b/frontend/src/language/en/app.po @@ -9,21 +9,21 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: src/routes/index.ts:116 +#: src/routes/index.ts:125 msgid "About" msgstr "About" -#: src/routes/index.ts:99 src/views/domain/ngx_conf/LogEntry.vue:64 +#: src/routes/index.ts:100 src/views/domain/ngx_conf/LogEntry.vue:64 msgid "Access Logs" msgstr "" -#: src/views/config/Config.vue:24 src/views/domain/DomainList.vue:42 +#: src/views/config/Config.vue:24 src/views/domain/DomainList.vue:47 #: src/views/user/User.vue:43 msgid "Action" msgstr "Action" -#: src/components/StdDataDisplay/StdCurd.vue:134 -#: src/components/StdDataDisplay/StdCurd.vue:26 +#: src/components/StdDataDisplay/StdCurd.vue:145 +#: src/components/StdDataDisplay/StdCurd.vue:25 msgid "Add" msgstr "" @@ -33,47 +33,53 @@ msgstr "" msgid "Add Directive Below" msgstr "Add Directive Below" -#: src/views/domain/ngx_conf/LocationEditor.vue:33 -#: src/views/domain/ngx_conf/LocationEditor.vue:48 +#: src/views/domain/ngx_conf/LocationEditor.vue:45 +#: src/views/domain/ngx_conf/LocationEditor.vue:50 +#: src/views/domain/ngx_conf/LocationEditor.vue:51 +#: src/views/domain/ngx_conf/LocationEditor.vue:60 msgid "Add Location" msgstr "Add Location" -#: src/routes/index.ts:55 src/views/domain/DomainAdd.vue:2 +#: src/routes/index.ts:56 src/views/domain/DomainAdd.vue:2 msgid "Add Site" msgstr "Add Site" -#: src/views/domain/DomainEdit.vue:19 +#: src/views/domain/DomainEdit.vue:18 src/views/domain/DomainEdit.vue:19 msgid "Advance Mode" msgstr "Advance Mode" -#: src/components/StdDataDisplay/StdTable.vue:44 -#: src/views/domain/DomainList.vue:27 +#: src/components/StdDataDisplay/StdTable.vue:54 +#: src/views/domain/DomainList.vue:26 #, fuzzy -msgid "Are you sure you want to delete ?" +msgid "Are you sure you want to delete?" msgstr "Are you sure you want to remove this directive?" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:15 +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:27 msgid "Are you sure you want to remove this directive?" msgstr "Are you sure you want to remove this directive?" -#: src/views/domain/ngx_conf/LocationEditor.vue:9 +#: src/views/domain/ngx_conf/LocationEditor.vue:19 #, fuzzy msgid "Are you sure you want to remove this location?" msgstr "Are you sure you want to remove this directive?" +#: src/views/preference/Preference.vue:7 src/views/preference/Preference.vue:8 +msgid "Auto" +msgstr "" + #: src/views/nginx_log/NginxLog.vue:4 msgid "Auto Refresh" msgstr "" -#: src/views/domain/cert/IssueCert.vue:78 +#: src/views/domain/cert/IssueCert.vue:72 msgid "Auto-renewal disabled for %{name}" msgstr "Auto-renewal disabled for %{name}" -#: src/views/domain/cert/IssueCert.vue:72 +#: src/views/domain/cert/IssueCert.vue:66 msgid "Auto-renewal enabled for %{name}" msgstr "Auto-renewal enabled for %{name}" -#: src/views/domain/DomainEdit.vue:178 src/views/nginx_log/NginxLog.vue:172 +#: src/views/domain/DomainEdit.vue:187 src/views/nginx_log/NginxLog.vue:173 msgid "Back" msgstr "Back" @@ -86,15 +92,25 @@ msgstr "Back" msgid "Base information" msgstr "Base information" -#: src/views/domain/DomainEdit.vue:22 +#: src/views/domain/DomainEdit.vue:21 src/views/domain/DomainEdit.vue:22 msgid "Basic Mode" msgstr "Basic Mode" +#: src/components/StdDataDisplay/StdBatchEdit.vue:5 +#: src/components/StdDataDisplay/StdTable.vue:12 +#: src/components/StdDataDisplay/StdTable.vue:13 +#: src/components/StdDataDisplay/StdTable.vue:18 +#, fuzzy +msgid "Batch Modify" +msgstr "Modify Config" + #: src/views/other/About.vue:21 msgid "Build with" msgstr "Build with" -#: src/components/StdDataDisplay/StdCurd.vue:28 +#: src/components/StdDataDisplay/StdBatchEdit.vue:7 +#: src/components/StdDataDisplay/StdCurd.vue:27 +#: src/components/StdDataEntry/components/StdSelector.vue:11 #: src/components/StdDataEntry/compontents/StdSelector.vue:11 #: src/views/config/ConfigEdit.vue:49 msgid "Cancel" @@ -112,9 +128,9 @@ msgstr "Certificate is valid" msgid "Certificate Status" msgstr "Certificate Status" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29 -#: src/views/domain/ngx_conf/LocationEditor.vue:21 -#: src/views/domain/ngx_conf/LocationEditor.vue:35 +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:41 +#: src/views/domain/ngx_conf/LocationEditor.vue:31 +#: src/views/domain/ngx_conf/LocationEditor.vue:47 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 msgid "Comments" msgstr "Comments" @@ -131,8 +147,8 @@ msgstr "Configurations" msgid "Configure SSL" msgstr "Configure SSL" -#: src/views/domain/ngx_conf/LocationEditor.vue:27 -#: src/views/domain/ngx_conf/LocationEditor.vue:41 +#: src/views/domain/ngx_conf/LocationEditor.vue:37 +#: src/views/domain/ngx_conf/LocationEditor.vue:53 msgid "Content" msgstr "Content" @@ -156,7 +172,12 @@ msgstr "Created at" msgid "Creating client facilitates communication with the CA server" msgstr "" -#: src/routes/index.ts:27 +#: src/views/preference/Preference.vue:13 +#: src/views/preference/Preference.vue:14 +msgid "Dark" +msgstr "" + +#: src/routes/index.ts:28 msgid "Dashboard" msgstr "Dashboard" @@ -164,16 +185,16 @@ msgstr "Dashboard" msgid "Database (Optional, default: database)" msgstr "Database (Optional, default: database)" -#: src/components/StdDataDisplay/StdTable.vue:366 -#: src/views/domain/DomainList.vue:111 +#: src/components/StdDataDisplay/StdTable.vue:527 +#: src/views/domain/DomainList.vue:115 msgid "Delete" msgstr "" -#: src/components/StdDataDisplay/StdTable.vue:120 +#: src/components/StdDataDisplay/StdTable.vue:132 msgid "Delete ID: %{id}" msgstr "" -#: src/views/domain/DomainList.vue:76 +#: src/views/domain/DomainList.vue:81 msgid "Delete site: %{site_name}" msgstr "" @@ -185,20 +206,23 @@ msgstr "Development Mode" msgid "Directive" msgstr "Directive" +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:1 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:2 msgid "Directives" msgstr "Directives" -#: src/views/domain/cert/IssueCert.vue:80 +#: src/views/domain/cert/IssueCert.vue:74 msgid "Disable auto-renewal failed for %{name}" msgstr "Disable auto-renewal failed for %{name}" -#: src/views/domain/DomainEdit.vue:10 src/views/domain/DomainList.vue:17 -#: src/views/domain/DomainList.vue:29 +#: src/views/domain/DomainEdit.vue:10 src/views/domain/DomainEdit.vue:9 +#: src/views/domain/DomainList.vue:16 src/views/domain/DomainList.vue:34 +#: src/views/domain/DomainList.vue:7 src/views/domain/DomainList.vue:8 +#: src/views/domain/DomainList.vue:9 msgid "Disabled" msgstr "Disabled" -#: src/views/domain/DomainEdit.vue:112 src/views/domain/DomainList.vue:64 +#: src/views/domain/DomainEdit.vue:118 src/views/domain/DomainList.vue:69 msgid "Disabled successfully" msgstr "Disabled successfully" @@ -210,15 +234,15 @@ msgstr "Disk IO" msgid "Domain Config Created Successfully" msgstr "Domain Config Created Successfully" -#: src/views/domain/DomainEdit.vue:5 +#: src/views/domain/DomainEdit.vue:4 src/views/domain/DomainEdit.vue:5 msgid "Edit %{n}" msgstr "Edit %{n}" -#: src/routes/index.ts:77 src/views/config/ConfigEdit.vue:2 +#: src/routes/index.ts:78 src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "Edit Configuration" -#: src/routes/index.ts:59 +#: src/routes/index.ts:60 msgid "Edit Site" msgstr "Edit Site" @@ -226,7 +250,7 @@ msgstr "Edit Site" msgid "Email (*)" msgstr "Email (*)" -#: src/views/domain/cert/IssueCert.vue:74 +#: src/views/domain/cert/IssueCert.vue:68 msgid "Enable auto-renewal failed for %{name}" msgstr "Enable auto-renewal failed for %{name}" @@ -238,14 +262,15 @@ msgstr "Enable failed" msgid "Enable TLS" msgstr "Enable TLS" -#: src/views/domain/DomainEdit.vue:33 src/views/domain/DomainEdit.vue:7 -#: src/views/domain/DomainList.vue:12 src/views/domain/DomainList.vue:20 -#: src/views/domain/DomainList.vue:26 +#: src/views/domain/DomainEdit.vue:33 src/views/domain/DomainEdit.vue:6 +#: src/views/domain/DomainEdit.vue:7 src/views/domain/DomainList.vue:10 +#: src/views/domain/DomainList.vue:11 src/views/domain/DomainList.vue:12 +#: src/views/domain/DomainList.vue:19 src/views/domain/DomainList.vue:31 msgid "Enabled" msgstr "Enabled" -#: src/views/domain/DomainAdd.vue:46 src/views/domain/DomainEdit.vue:103 -#: src/views/domain/DomainList.vue:54 +#: src/views/domain/DomainAdd.vue:46 src/views/domain/DomainEdit.vue:109 +#: src/views/domain/DomainList.vue:59 msgid "Enabled successfully" msgstr "Enabled successfully" @@ -253,7 +278,7 @@ msgstr "Enabled successfully" msgid "Encrypt website with Let's Encrypt" msgstr "Encrypt website with Let's Encrypt" -#: src/routes/index.ts:103 src/views/domain/ngx_conf/LogEntry.vue:68 +#: src/routes/index.ts:104 src/views/domain/ngx_conf/LogEntry.vue:68 msgid "Error Logs" msgstr "" @@ -262,15 +287,17 @@ msgid "Expiration Date: %{date}" msgstr "Expiration Date: %{date}" #: src/components/StdDataDisplay/StdTable.vue:12 -#: src/components/StdDataDisplay/StdTable.vue:317 +#: src/components/StdDataDisplay/StdTable.vue:362 +#: src/components/StdDataDisplay/StdTable.vue:6 +#: src/components/StdDataDisplay/StdTable.vue:7 msgid "Export" msgstr "" -#: src/views/domain/DomainEdit.vue:115 src/views/domain/DomainList.vue:68 +#: src/views/domain/DomainEdit.vue:121 src/views/domain/DomainList.vue:73 msgid "Failed to disable %{msg}" msgstr "Failed to disable %{msg}" -#: src/views/domain/DomainEdit.vue:106 src/views/domain/DomainList.vue:58 +#: src/views/domain/DomainEdit.vue:112 src/views/domain/DomainList.vue:63 msgid "Failed to enable %{msg}" msgstr "Failed to enable %{msg}" @@ -290,6 +317,7 @@ msgstr "" msgid "Finished" msgstr "Finished" +#: src/components/StdDataEntry/components/StdPassword.vue:42 #: src/components/StdDataEntry/compontents/StdPassword.vue:42 msgid "Generate" msgstr "" @@ -298,15 +326,15 @@ msgstr "" msgid "Generating private key for registering account" msgstr "" -#: src/views/domain/cert/IssueCert.vue:103 +#: src/views/domain/cert/IssueCert.vue:97 msgid "Getting the certificate, please wait..." msgstr "Getting the certificate, please wait..." -#: src/routes/index.ts:20 +#: src/routes/index.ts:21 msgid "Home" msgstr "Home" -#: src/routes/index.ts:126 src/views/other/Install.vue:128 +#: src/routes/index.ts:135 src/views/other/Install.vue:128 msgid "Install" msgstr "Install" @@ -328,19 +356,26 @@ msgstr "Enabled successfully" msgid "Leave blank for no change" msgstr "Leave blank for no change" +#: src/views/preference/Preference.vue:10 +#: src/views/preference/Preference.vue:11 +msgid "Light" +msgstr "" + #: src/views/dashboard/DashBoard.vue:141 msgid "Load Averages:" msgstr "Load Averages:" -#: src/views/domain/ngx_conf/LocationEditor.vue:5 +#: src/views/domain/ngx_conf/LocationEditor.vue:15 +#: src/views/domain/ngx_conf/LocationEditor.vue:8 +#: src/views/domain/ngx_conf/LocationEditor.vue:9 msgid "Location" msgstr "Location" -#: src/views/domain/ngx_conf/LocationEditor.vue:39 +#: src/views/domain/ngx_conf/LocationEditor.vue:40 msgid "Locations" msgstr "Locations" -#: src/routes/index.ts:132 src/views/other/Login.vue:103 +#: src/routes/index.ts:141 src/views/other/Login.vue:103 msgid "Login" msgstr "Login" @@ -352,7 +387,7 @@ msgstr "Login successful" msgid "Logout successful" msgstr "Logout successful" -#: src/views/domain/cert/IssueCert.vue:226 +#: src/views/domain/cert/IssueCert.vue:209 msgid "" "Make sure you have configured a reverse proxy for .well-known directory to " "HTTPChallengePort (default: 9180) before getting the certificate." @@ -360,15 +395,15 @@ msgstr "" "Make sure you have configured a reverse proxy for .well-known directory to " "HTTPChallengePort (default: 9180) before getting the certificate." -#: src/routes/index.ts:68 +#: src/routes/index.ts:69 msgid "Manage Configs" msgstr "Manage Configs" -#: src/routes/index.ts:43 src/views/domain/DomainList.vue:2 +#: src/routes/index.ts:44 src/views/domain/DomainList.vue:2 msgid "Manage Sites" msgstr "Manage Sites" -#: src/routes/index.ts:35 src/views/user/User.vue:2 +#: src/routes/index.ts:36 src/views/user/User.vue:2 msgid "Manage Users" msgstr "Manage Users" @@ -380,12 +415,12 @@ msgstr "Memory" msgid "Memory and Storage" msgstr "Memory and Storage" -#: src/components/StdDataDisplay/StdCurd.vue:26 -#: src/components/StdDataDisplay/StdTable.vue:18 -#: src/components/StdDataDisplay/StdTable.vue:19 -#: src/components/StdDataDisplay/StdTable.vue:24 -#: src/components/StdDataDisplay/StdTable.vue:34 -#: src/components/StdDataDisplay/StdTable.vue:36 +#: src/components/StdDataDisplay/StdCurd.vue:25 +#: src/components/StdDataDisplay/StdTable.vue:25 +#: src/components/StdDataDisplay/StdTable.vue:26 +#: src/components/StdDataDisplay/StdTable.vue:31 +#: src/components/StdDataDisplay/StdTable.vue:44 +#: src/components/StdDataDisplay/StdTable.vue:46 #, fuzzy msgid "Modify" msgstr "Modify Config" @@ -394,7 +429,8 @@ msgstr "Modify Config" msgid "Modify Config" msgstr "Modify Config" -#: src/views/config/Config.vue:12 src/views/domain/DomainList.vue:14 +#: src/views/config/Config.vue:12 src/views/domain/DomainEdit.vue:36 +#: src/views/domain/DomainList.vue:15 msgid "Name" msgstr "Name" @@ -418,18 +454,18 @@ msgstr "Network Total Send" msgid "Next" msgstr "Next" -#: src/routes/index.ts:93 src/views/nginx_log/NginxLog.vue:2 +#: src/routes/index.ts:94 src/views/nginx_log/NginxLog.vue:2 msgid "Nginx Log" msgstr "" -#: src/components/StdDataDisplay/StdTable.vue:42 -#: src/views/domain/DomainList.vue:25 -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:17 -#: src/views/domain/ngx_conf/LocationEditor.vue:11 +#: src/components/StdDataDisplay/StdTable.vue:52 +#: src/views/domain/DomainList.vue:24 +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29 +#: src/views/domain/ngx_conf/LocationEditor.vue:21 msgid "No" msgstr "No" -#: src/routes/index.ts:138 src/routes/index.ts:140 +#: src/routes/index.ts:147 src/routes/index.ts:149 msgid "Not Found" msgstr "Not Found" @@ -437,7 +473,7 @@ msgstr "Not Found" msgid "Not Valid Before: %{date}" msgstr "Not Valid Before: %{date}" -#: src/views/domain/cert/IssueCert.vue:218 +#: src/views/domain/cert/IssueCert.vue:201 msgid "" "Note: The server_name in the current configuration must be the domain name " "you need to get the certificate." @@ -449,10 +485,12 @@ msgstr "" msgid "Obtaining certificate" msgstr "" -#: src/components/StdDataDisplay/StdCurd.vue:29 -#: src/components/StdDataDisplay/StdTable.vue:43 +#: src/components/StdDataDisplay/StdBatchEdit.vue:8 +#: src/components/StdDataDisplay/StdCurd.vue:28 +#: src/components/StdDataDisplay/StdTable.vue:53 +#: src/components/StdDataEntry/components/StdSelector.vue:12 #: src/components/StdDataEntry/compontents/StdSelector.vue:12 -#: src/views/domain/DomainList.vue:26 +#: src/views/domain/DomainList.vue:25 msgid "OK" msgstr "" @@ -472,8 +510,8 @@ msgstr "Password" msgid "Password (*)" msgstr "Password (*)" -#: src/views/domain/ngx_conf/LocationEditor.vue:24 -#: src/views/domain/ngx_conf/LocationEditor.vue:38 +#: src/views/domain/ngx_conf/LocationEditor.vue:34 +#: src/views/domain/ngx_conf/LocationEditor.vue:50 msgid "Path" msgstr "Path" @@ -489,6 +527,10 @@ msgstr "Please input your password!" msgid "Please input your username!" msgstr "Please input your username!" +#: src/routes/index.ts:117 src/views/preference/Preference.vue:2 +msgid "Preference" +msgstr "" + #: src/language/constants.ts:12 #, fuzzy msgid "Preparing lego configurations" @@ -522,11 +564,15 @@ msgstr "" msgid "Reloading nginx" msgstr "" +#: src/components/StdDataDisplay/StdTable.vue:10 #: src/components/StdDataDisplay/StdTable.vue:15 +#: src/components/StdDataDisplay/StdTable.vue:9 msgid "Reset" msgstr "" -#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:181 +#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:190 +#: src/views/preference/Preference.vue:22 +#: src/views/preference/Preference.vue:23 msgid "Save" msgstr "Save" @@ -540,16 +586,22 @@ msgstr "Save Directive" msgid "Save error %{msg}" msgstr "Save error %{msg}" -#: src/components/StdDataDisplay/StdCurd.vue:102 +#: src/components/StdDataDisplay/StdBatchEdit.vue:40 +#, fuzzy +msgid "Save successfully" +msgstr "Saved successfully" + +#: src/components/StdDataDisplay/StdCurd.vue:108 #, fuzzy msgid "Save Successfully" msgstr "Saved successfully" #: src/views/config/ConfigEdit.vue:34 src/views/domain/DomainAdd.vue:43 -#: src/views/domain/DomainEdit.vue:91 +#: src/views/domain/DomainEdit.vue:97 msgid "Saved successfully" msgstr "Saved successfully" +#: src/components/StdDataEntry/components/StdSelector.vue:13 #: src/components/StdDataEntry/compontents/StdSelector.vue:13 msgid "Selector" msgstr "" @@ -558,11 +610,13 @@ msgstr "" msgid "Send" msgstr "Send" -#: src/components/StdDataDisplay/StdTable.vue:140 -#: src/components/StdDataDisplay/StdTable.vue:298 -#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:56 -#: src/views/domain/DomainEdit.vue:68 src/views/domain/DomainEdit.vue:77 -#: src/views/domain/DomainEdit.vue:94 src/views/domain/DomainList.vue:78 +#: src/components/StdDataDisplay/StdBatchEdit.vue:43 +#: src/components/StdDataDisplay/StdTable.vue:168 +#: src/components/StdDataDisplay/StdTable.vue:343 +#: src/components/StdDataDisplay/StdTable.vue:463 +#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:100 +#: src/views/domain/DomainEdit.vue:62 src/views/domain/DomainEdit.vue:74 +#: src/views/domain/DomainEdit.vue:83 src/views/domain/DomainList.vue:83 #: src/views/other/Install.vue:71 msgid "Server error" msgstr "Server error" @@ -575,29 +629,25 @@ msgstr "Server Info" msgid "server_name not found in directives" msgstr "server_name not found in directives" -#: src/views/domain/cert/IssueCert.vue:209 src/views/domain/DomainAdd.vue:112 +#: src/views/domain/cert/IssueCert.vue:195 src/views/domain/DomainAdd.vue:112 msgid "server_name parameter is required" msgstr "server_name parameter is required" -#: src/views/domain/cert/IssueCert.vue:212 -#: src/views/domain/cert/IssueCert.vue:35 -msgid "server_name parameters more than one" -msgstr "server_name parameters more than one" - +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:6 #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:7 msgid "Single Directive" msgstr "Single Directive" -#: src/routes/index.ts:107 +#: src/routes/index.ts:108 #, fuzzy msgid "Site Logs" msgstr "Sites List" -#: src/routes/index.ts:51 +#: src/routes/index.ts:52 msgid "Sites List" msgstr "Sites List" -#: src/views/domain/DomainList.vue:19 +#: src/views/domain/DomainList.vue:24 msgid "Status" msgstr "Status" @@ -618,11 +668,11 @@ msgstr "Swap" msgid "Table" msgstr "Enabled" -#: src/routes/index.ts:85 src/views/pty/Terminal.vue:2 +#: src/routes/index.ts:86 src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "Terminal" -#: src/views/domain/cert/IssueCert.vue:222 +#: src/views/domain/cert/IssueCert.vue:205 msgid "" "The certificate for the domain will be checked every hour, and will be " "renewed if it has been more than 1 month since it was last issued." @@ -638,11 +688,20 @@ msgstr "The filename cannot contain the following characters: %{c}" msgid "The username or password is incorrect" msgstr "" -#: src/views/config/Config.vue:17 src/views/domain/DomainList.vue:36 +#: src/views/preference/Preference.vue:5 +msgid "Theme" +msgstr "" + +#: src/views/config/Config.vue:17 src/views/domain/DomainList.vue:41 #: src/views/user/User.vue:37 msgid "Updated at" msgstr "Updated at" +#: src/components/StdDataDisplay/StdTable.vue:461 +#, fuzzy +msgid "Updated successfully" +msgstr "Saved successfully" + #: src/views/dashboard/DashBoard.vue:137 msgid "Uptime:" msgstr "Uptime:" @@ -676,8 +735,8 @@ msgstr "" msgid "Writing certificate to disk" msgstr "" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:16 -#: src/views/domain/ngx_conf/LocationEditor.vue:10 +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:28 +#: src/views/domain/ngx_conf/LocationEditor.vue:20 msgid "Yes" msgstr "Yes" @@ -686,6 +745,13 @@ msgctxt "Project" msgid "License" msgstr "License" +#, fuzzy +#~ msgid "Are you sure you want to delete ?" +#~ msgstr "Are you sure you want to remove this directive?" + +#~ msgid "server_name parameters more than one" +#~ msgstr "server_name parameters more than one" + #~ msgid "404 Not Found" #~ msgstr "404 Not Found" diff --git a/frontend/src/language/messages.pot b/frontend/src/language/messages.pot index 98eacab38..d8dbb625e 100644 --- a/frontend/src/language/messages.pot +++ b/frontend/src/language/messages.pot @@ -2,23 +2,23 @@ msgid "" msgstr "" "Content-Type: text/plain; charset=UTF-8\n" -#: src/routes/index.ts:116 +#: src/routes/index.ts:125 msgid "About" msgstr "" -#: src/routes/index.ts:99 +#: src/routes/index.ts:100 #: src/views/domain/ngx_conf/LogEntry.vue:64 msgid "Access Logs" msgstr "" #: src/views/config/Config.vue:24 -#: src/views/domain/DomainList.vue:42 +#: src/views/domain/DomainList.vue:47 #: src/views/user/User.vue:43 msgid "Action" msgstr "" -#: src/components/StdDataDisplay/StdCurd.vue:134 -#: src/components/StdDataDisplay/StdCurd.vue:26 +#: src/components/StdDataDisplay/StdCurd.vue:145 +#: src/components/StdDataDisplay/StdCurd.vue:25 msgid "Add" msgstr "" @@ -28,47 +28,55 @@ msgstr "" msgid "Add Directive Below" msgstr "" -#: src/views/domain/ngx_conf/LocationEditor.vue:33 -#: src/views/domain/ngx_conf/LocationEditor.vue:48 +#: src/views/domain/ngx_conf/LocationEditor.vue:45 +#: src/views/domain/ngx_conf/LocationEditor.vue:50 +#: src/views/domain/ngx_conf/LocationEditor.vue:51 +#: src/views/domain/ngx_conf/LocationEditor.vue:60 msgid "Add Location" msgstr "" -#: src/routes/index.ts:55 +#: src/routes/index.ts:56 #: src/views/domain/DomainAdd.vue:2 msgid "Add Site" msgstr "" +#: src/views/domain/DomainEdit.vue:18 #: src/views/domain/DomainEdit.vue:19 msgid "Advance Mode" msgstr "" -#: src/components/StdDataDisplay/StdTable.vue:44 -#: src/views/domain/DomainList.vue:27 -msgid "Are you sure you want to delete ?" +#: src/components/StdDataDisplay/StdTable.vue:54 +#: src/views/domain/DomainList.vue:26 +msgid "Are you sure you want to delete?" msgstr "" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:15 +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:27 msgid "Are you sure you want to remove this directive?" msgstr "" -#: src/views/domain/ngx_conf/LocationEditor.vue:9 +#: src/views/domain/ngx_conf/LocationEditor.vue:19 msgid "Are you sure you want to remove this location?" msgstr "" +#: src/views/preference/Preference.vue:7 +#: src/views/preference/Preference.vue:8 +msgid "Auto" +msgstr "" + #: src/views/nginx_log/NginxLog.vue:4 msgid "Auto Refresh" msgstr "" -#: src/views/domain/cert/IssueCert.vue:78 +#: src/views/domain/cert/IssueCert.vue:72 msgid "Auto-renewal disabled for %{name}" msgstr "" -#: src/views/domain/cert/IssueCert.vue:72 +#: src/views/domain/cert/IssueCert.vue:66 msgid "Auto-renewal enabled for %{name}" msgstr "" -#: src/views/domain/DomainEdit.vue:178 -#: src/views/nginx_log/NginxLog.vue:172 +#: src/views/domain/DomainEdit.vue:187 +#: src/views/nginx_log/NginxLog.vue:173 msgid "Back" msgstr "" @@ -80,15 +88,25 @@ msgstr "" msgid "Base information" msgstr "" +#: src/views/domain/DomainEdit.vue:21 #: src/views/domain/DomainEdit.vue:22 msgid "Basic Mode" msgstr "" +#: src/components/StdDataDisplay/StdBatchEdit.vue:5 +#: src/components/StdDataDisplay/StdTable.vue:12 +#: src/components/StdDataDisplay/StdTable.vue:13 +#: src/components/StdDataDisplay/StdTable.vue:18 +msgid "Batch Modify" +msgstr "" + #: src/views/other/About.vue:21 msgid "Build with" msgstr "" -#: src/components/StdDataDisplay/StdCurd.vue:28 +#: src/components/StdDataDisplay/StdBatchEdit.vue:7 +#: src/components/StdDataDisplay/StdCurd.vue:27 +#: src/components/StdDataEntry/components/StdSelector.vue:11 #: src/components/StdDataEntry/compontents/StdSelector.vue:11 #: src/views/config/ConfigEdit.vue:49 msgid "Cancel" @@ -106,9 +124,9 @@ msgstr "" msgid "Certificate Status" msgstr "" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29 -#: src/views/domain/ngx_conf/LocationEditor.vue:21 -#: src/views/domain/ngx_conf/LocationEditor.vue:35 +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:41 +#: src/views/domain/ngx_conf/LocationEditor.vue:31 +#: src/views/domain/ngx_conf/LocationEditor.vue:47 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 msgid "Comments" msgstr "" @@ -125,8 +143,8 @@ msgstr "" msgid "Configure SSL" msgstr "" -#: src/views/domain/ngx_conf/LocationEditor.vue:27 -#: src/views/domain/ngx_conf/LocationEditor.vue:41 +#: src/views/domain/ngx_conf/LocationEditor.vue:37 +#: src/views/domain/ngx_conf/LocationEditor.vue:53 msgid "Content" msgstr "" @@ -150,7 +168,12 @@ msgstr "" msgid "Creating client facilitates communication with the CA server" msgstr "" -#: src/routes/index.ts:27 +#: src/views/preference/Preference.vue:13 +#: src/views/preference/Preference.vue:14 +msgid "Dark" +msgstr "" + +#: src/routes/index.ts:28 msgid "Dashboard" msgstr "" @@ -158,16 +181,16 @@ msgstr "" msgid "Database (Optional, default: database)" msgstr "" -#: src/components/StdDataDisplay/StdTable.vue:366 -#: src/views/domain/DomainList.vue:111 +#: src/components/StdDataDisplay/StdTable.vue:527 +#: src/views/domain/DomainList.vue:115 msgid "Delete" msgstr "" -#: src/components/StdDataDisplay/StdTable.vue:120 +#: src/components/StdDataDisplay/StdTable.vue:132 msgid "Delete ID: %{id}" msgstr "" -#: src/views/domain/DomainList.vue:76 +#: src/views/domain/DomainList.vue:81 msgid "Delete site: %{site_name}" msgstr "" @@ -180,22 +203,27 @@ msgstr "" msgid "Directive" msgstr "" +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:1 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:2 msgid "Directives" msgstr "" -#: src/views/domain/cert/IssueCert.vue:80 +#: src/views/domain/cert/IssueCert.vue:74 msgid "Disable auto-renewal failed for %{name}" msgstr "" #: src/views/domain/DomainEdit.vue:10 -#: src/views/domain/DomainList.vue:17 -#: src/views/domain/DomainList.vue:29 +#: src/views/domain/DomainEdit.vue:9 +#: src/views/domain/DomainList.vue:16 +#: src/views/domain/DomainList.vue:34 +#: src/views/domain/DomainList.vue:7 +#: src/views/domain/DomainList.vue:8 +#: src/views/domain/DomainList.vue:9 msgid "Disabled" msgstr "" -#: src/views/domain/DomainEdit.vue:112 -#: src/views/domain/DomainList.vue:64 +#: src/views/domain/DomainEdit.vue:118 +#: src/views/domain/DomainList.vue:69 msgid "Disabled successfully" msgstr "" @@ -207,16 +235,17 @@ msgstr "" msgid "Domain Config Created Successfully" msgstr "" +#: src/views/domain/DomainEdit.vue:4 #: src/views/domain/DomainEdit.vue:5 msgid "Edit %{n}" msgstr "" -#: src/routes/index.ts:77 +#: src/routes/index.ts:78 #: src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "" -#: src/routes/index.ts:59 +#: src/routes/index.ts:60 msgid "Edit Site" msgstr "" @@ -224,7 +253,7 @@ msgstr "" msgid "Email (*)" msgstr "" -#: src/views/domain/cert/IssueCert.vue:74 +#: src/views/domain/cert/IssueCert.vue:68 msgid "Enable auto-renewal failed for %{name}" msgstr "" @@ -237,16 +266,19 @@ msgid "Enable TLS" msgstr "" #: src/views/domain/DomainEdit.vue:33 +#: src/views/domain/DomainEdit.vue:6 #: src/views/domain/DomainEdit.vue:7 +#: src/views/domain/DomainList.vue:10 +#: src/views/domain/DomainList.vue:11 #: src/views/domain/DomainList.vue:12 -#: src/views/domain/DomainList.vue:20 -#: src/views/domain/DomainList.vue:26 +#: src/views/domain/DomainList.vue:19 +#: src/views/domain/DomainList.vue:31 msgid "Enabled" msgstr "" #: src/views/domain/DomainAdd.vue:46 -#: src/views/domain/DomainEdit.vue:103 -#: src/views/domain/DomainList.vue:54 +#: src/views/domain/DomainEdit.vue:109 +#: src/views/domain/DomainList.vue:59 msgid "Enabled successfully" msgstr "" @@ -254,7 +286,7 @@ msgstr "" msgid "Encrypt website with Let's Encrypt" msgstr "" -#: src/routes/index.ts:103 +#: src/routes/index.ts:104 #: src/views/domain/ngx_conf/LogEntry.vue:68 msgid "Error Logs" msgstr "" @@ -264,17 +296,19 @@ msgid "Expiration Date: %{date}" msgstr "" #: src/components/StdDataDisplay/StdTable.vue:12 -#: src/components/StdDataDisplay/StdTable.vue:317 +#: src/components/StdDataDisplay/StdTable.vue:362 +#: src/components/StdDataDisplay/StdTable.vue:6 +#: src/components/StdDataDisplay/StdTable.vue:7 msgid "Export" msgstr "" -#: src/views/domain/DomainEdit.vue:115 -#: src/views/domain/DomainList.vue:68 +#: src/views/domain/DomainEdit.vue:121 +#: src/views/domain/DomainList.vue:73 msgid "Failed to disable %{msg}" msgstr "" -#: src/views/domain/DomainEdit.vue:106 -#: src/views/domain/DomainList.vue:58 +#: src/views/domain/DomainEdit.vue:112 +#: src/views/domain/DomainList.vue:63 msgid "Failed to enable %{msg}" msgstr "" @@ -296,6 +330,7 @@ msgstr "" msgid "Finished" msgstr "" +#: src/components/StdDataEntry/components/StdPassword.vue:42 #: src/components/StdDataEntry/compontents/StdPassword.vue:42 msgid "Generate" msgstr "" @@ -304,15 +339,15 @@ msgstr "" msgid "Generating private key for registering account" msgstr "" -#: src/views/domain/cert/IssueCert.vue:103 +#: src/views/domain/cert/IssueCert.vue:97 msgid "Getting the certificate, please wait..." msgstr "" -#: src/routes/index.ts:20 +#: src/routes/index.ts:21 msgid "Home" msgstr "" -#: src/routes/index.ts:126 +#: src/routes/index.ts:135 #: src/views/other/Install.vue:128 msgid "Install" msgstr "" @@ -333,19 +368,26 @@ msgstr "" msgid "Leave blank for no change" msgstr "" +#: src/views/preference/Preference.vue:10 +#: src/views/preference/Preference.vue:11 +msgid "Light" +msgstr "" + #: src/views/dashboard/DashBoard.vue:141 msgid "Load Averages:" msgstr "" -#: src/views/domain/ngx_conf/LocationEditor.vue:5 +#: src/views/domain/ngx_conf/LocationEditor.vue:15 +#: src/views/domain/ngx_conf/LocationEditor.vue:8 +#: src/views/domain/ngx_conf/LocationEditor.vue:9 msgid "Location" msgstr "" -#: src/views/domain/ngx_conf/LocationEditor.vue:39 +#: src/views/domain/ngx_conf/LocationEditor.vue:40 msgid "Locations" msgstr "" -#: src/routes/index.ts:132 +#: src/routes/index.ts:141 #: src/views/other/Login.vue:103 msgid "Login" msgstr "" @@ -358,20 +400,20 @@ msgstr "" msgid "Logout successful" msgstr "" -#: src/views/domain/cert/IssueCert.vue:226 +#: src/views/domain/cert/IssueCert.vue:209 msgid "Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate." msgstr "" -#: src/routes/index.ts:68 +#: src/routes/index.ts:69 msgid "Manage Configs" msgstr "" -#: src/routes/index.ts:43 +#: src/routes/index.ts:44 #: src/views/domain/DomainList.vue:2 msgid "Manage Sites" msgstr "" -#: src/routes/index.ts:35 +#: src/routes/index.ts:36 #: src/views/user/User.vue:2 msgid "Manage Users" msgstr "" @@ -384,12 +426,12 @@ msgstr "" msgid "Memory and Storage" msgstr "" -#: src/components/StdDataDisplay/StdCurd.vue:26 -#: src/components/StdDataDisplay/StdTable.vue:18 -#: src/components/StdDataDisplay/StdTable.vue:19 -#: src/components/StdDataDisplay/StdTable.vue:24 -#: src/components/StdDataDisplay/StdTable.vue:34 -#: src/components/StdDataDisplay/StdTable.vue:36 +#: src/components/StdDataDisplay/StdCurd.vue:25 +#: src/components/StdDataDisplay/StdTable.vue:25 +#: src/components/StdDataDisplay/StdTable.vue:26 +#: src/components/StdDataDisplay/StdTable.vue:31 +#: src/components/StdDataDisplay/StdTable.vue:44 +#: src/components/StdDataDisplay/StdTable.vue:46 msgid "Modify" msgstr "" @@ -398,7 +440,8 @@ msgid "Modify Config" msgstr "" #: src/views/config/Config.vue:12 -#: src/views/domain/DomainList.vue:14 +#: src/views/domain/DomainEdit.vue:36 +#: src/views/domain/DomainList.vue:15 msgid "Name" msgstr "" @@ -422,20 +465,20 @@ msgstr "" msgid "Next" msgstr "" -#: src/routes/index.ts:93 +#: src/routes/index.ts:94 #: src/views/nginx_log/NginxLog.vue:2 msgid "Nginx Log" msgstr "" -#: src/components/StdDataDisplay/StdTable.vue:42 -#: src/views/domain/DomainList.vue:25 -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:17 -#: src/views/domain/ngx_conf/LocationEditor.vue:11 +#: src/components/StdDataDisplay/StdTable.vue:52 +#: src/views/domain/DomainList.vue:24 +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29 +#: src/views/domain/ngx_conf/LocationEditor.vue:21 msgid "No" msgstr "" -#: src/routes/index.ts:138 -#: src/routes/index.ts:140 +#: src/routes/index.ts:147 +#: src/routes/index.ts:149 msgid "Not Found" msgstr "" @@ -443,7 +486,7 @@ msgstr "" msgid "Not Valid Before: %{date}" msgstr "" -#: src/views/domain/cert/IssueCert.vue:218 +#: src/views/domain/cert/IssueCert.vue:201 msgid "Note: The server_name in the current configuration must be the domain name you need to get the certificate." msgstr "" @@ -452,10 +495,12 @@ msgstr "" msgid "Obtaining certificate" msgstr "" -#: src/components/StdDataDisplay/StdCurd.vue:29 -#: src/components/StdDataDisplay/StdTable.vue:43 +#: src/components/StdDataDisplay/StdBatchEdit.vue:8 +#: src/components/StdDataDisplay/StdCurd.vue:28 +#: src/components/StdDataDisplay/StdTable.vue:53 +#: src/components/StdDataEntry/components/StdSelector.vue:12 #: src/components/StdDataEntry/compontents/StdSelector.vue:12 -#: src/views/domain/DomainList.vue:26 +#: src/views/domain/DomainList.vue:25 msgid "OK" msgstr "" @@ -476,8 +521,8 @@ msgstr "" msgid "Password (*)" msgstr "" -#: src/views/domain/ngx_conf/LocationEditor.vue:24 -#: src/views/domain/ngx_conf/LocationEditor.vue:38 +#: src/views/domain/ngx_conf/LocationEditor.vue:34 +#: src/views/domain/ngx_conf/LocationEditor.vue:50 msgid "Path" msgstr "" @@ -495,6 +540,11 @@ msgstr "" msgid "Please input your username!" msgstr "" +#: src/routes/index.ts:117 +#: src/views/preference/Preference.vue:2 +msgid "Preference" +msgstr "" + #: src/language/constants.ts:12 msgid "Preparing lego configurations" msgstr "" @@ -528,12 +578,16 @@ msgstr "" msgid "Reloading nginx" msgstr "" +#: src/components/StdDataDisplay/StdTable.vue:10 #: src/components/StdDataDisplay/StdTable.vue:15 +#: src/components/StdDataDisplay/StdTable.vue:9 msgid "Reset" msgstr "" #: src/views/config/ConfigEdit.vue:52 -#: src/views/domain/DomainEdit.vue:181 +#: src/views/domain/DomainEdit.vue:190 +#: src/views/preference/Preference.vue:22 +#: src/views/preference/Preference.vue:23 msgid "Save" msgstr "" @@ -548,16 +602,21 @@ msgstr "" msgid "Save error %{msg}" msgstr "" -#: src/components/StdDataDisplay/StdCurd.vue:102 +#: src/components/StdDataDisplay/StdBatchEdit.vue:40 +msgid "Save successfully" +msgstr "" + +#: src/components/StdDataDisplay/StdCurd.vue:108 msgid "Save Successfully" msgstr "" #: src/views/config/ConfigEdit.vue:34 #: src/views/domain/DomainAdd.vue:43 -#: src/views/domain/DomainEdit.vue:91 +#: src/views/domain/DomainEdit.vue:97 msgid "Saved successfully" msgstr "" +#: src/components/StdDataEntry/components/StdSelector.vue:13 #: src/components/StdDataEntry/compontents/StdSelector.vue:13 msgid "Selector" msgstr "" @@ -567,14 +626,16 @@ msgstr "" msgid "Send" msgstr "" -#: src/components/StdDataDisplay/StdTable.vue:140 -#: src/components/StdDataDisplay/StdTable.vue:298 +#: src/components/StdDataDisplay/StdBatchEdit.vue:43 +#: src/components/StdDataDisplay/StdTable.vue:168 +#: src/components/StdDataDisplay/StdTable.vue:343 +#: src/components/StdDataDisplay/StdTable.vue:463 #: src/views/config/ConfigEdit.vue:22 -#: src/views/domain/DomainEdit.vue:56 -#: src/views/domain/DomainEdit.vue:68 -#: src/views/domain/DomainEdit.vue:77 -#: src/views/domain/DomainEdit.vue:94 -#: src/views/domain/DomainList.vue:78 +#: src/views/domain/DomainEdit.vue:100 +#: src/views/domain/DomainEdit.vue:62 +#: src/views/domain/DomainEdit.vue:74 +#: src/views/domain/DomainEdit.vue:83 +#: src/views/domain/DomainList.vue:83 #: src/views/other/Install.vue:71 msgid "Server error" msgstr "" @@ -587,29 +648,25 @@ msgstr "" msgid "server_name not found in directives" msgstr "" -#: src/views/domain/cert/IssueCert.vue:209 +#: src/views/domain/cert/IssueCert.vue:195 #: src/views/domain/DomainAdd.vue:112 msgid "server_name parameter is required" msgstr "" -#: src/views/domain/cert/IssueCert.vue:212 -#: src/views/domain/cert/IssueCert.vue:35 -msgid "server_name parameters more than one" -msgstr "" - +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:6 #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:7 msgid "Single Directive" msgstr "" -#: src/routes/index.ts:107 +#: src/routes/index.ts:108 msgid "Site Logs" msgstr "" -#: src/routes/index.ts:51 +#: src/routes/index.ts:52 msgid "Sites List" msgstr "" -#: src/views/domain/DomainList.vue:19 +#: src/views/domain/DomainList.vue:24 msgid "Status" msgstr "" @@ -629,12 +686,12 @@ msgstr "" msgid "Table" msgstr "" -#: src/routes/index.ts:85 +#: src/routes/index.ts:86 #: src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "" -#: src/views/domain/cert/IssueCert.vue:222 +#: src/views/domain/cert/IssueCert.vue:205 msgid "The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued." msgstr "" @@ -646,12 +703,20 @@ msgstr "" msgid "The username or password is incorrect" msgstr "" +#: src/views/preference/Preference.vue:5 +msgid "Theme" +msgstr "" + #: src/views/config/Config.vue:17 -#: src/views/domain/DomainList.vue:36 +#: src/views/domain/DomainList.vue:41 #: src/views/user/User.vue:37 msgid "Updated at" msgstr "" +#: src/components/StdDataDisplay/StdTable.vue:461 +msgid "Updated successfully" +msgstr "" + #: src/views/dashboard/DashBoard.vue:137 msgid "Uptime:" msgstr "" @@ -688,8 +753,8 @@ msgstr "" msgid "Writing certificate to disk" msgstr "" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:16 -#: src/views/domain/ngx_conf/LocationEditor.vue:10 +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:28 +#: src/views/domain/ngx_conf/LocationEditor.vue:20 msgid "Yes" msgstr "" diff --git a/frontend/src/language/translations.json b/frontend/src/language/translations.json index ad4315e73..9f70a0142 100644 --- a/frontend/src/language/translations.json +++ b/frontend/src/language/translations.json @@ -1 +1 @@ -{"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Are you sure you want to delete ?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Comments":"注释","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","CPU Status":"CPU 状态","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Development Mode":"开发模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Domain Config Created Successfully":"域名配置文件创建成功","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Leave blank for no change":"留空表示不修改","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","Next":"下一步","Nginx Log":"Nginx 日志","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:当前配置中的 server_name 必须为需要申请证书的域名。","Obtaining certificate":"正在获取证书","OK":"确定","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reloading nginx":"正在重载 Nginx","Reset":"重置","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","server_name parameters more than one":"server_name 指令包含多个参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Table":"列表","Terminal":"终端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The username or password is incorrect":"用户名或密码错误","Updated at":"修改时间","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","License":{"Project":"开源许可"}},"zh_TW":{"About":"關於","Action":"操作","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Base information":"基本訊息","Basic Mode":"基本模式","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Comments":"註釋","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete ID: %{id}":"刪除 ID: %{id}","Development Mode":"開發模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Domain Config Created Successfully":"域名配置文件創建成功","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Expiration Date: %{date}":"過期時間: %{date}","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","File Not Found":"未找到檔案","Finished":"完成","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","Install":"安裝","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Leave blank for no change":"留空表示不修改","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify Config":"修改配置","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","Next":"下一步","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","OK":"確定","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Saved successfully":"儲存成功","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","server_name parameters more than one":"server_name 指令包含多個參數","Single Directive":"單行指令","Sites List":"站點列表","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","Terminal":"終端","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","Updated at":"修改時間","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Warning":"警告","Writes":"寫","Yes":"是的","License":{"Project":"開源軟體授權條款"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"Note: The server_name in the current configuration must be the domain name you need to get the certificate.","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","server_name parameters more than one":"server_name parameters more than one","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}}} \ No newline at end of file +{"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Auto":"自動","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Comments":"註釋","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Development Mode":"開發模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Domain Config Created Successfully":"域名配置文件創建成功","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error Logs":"錯誤日志","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","Next":"下一步","Nginx Log":"Nginx 日誌","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:當前配置中的 server_name 必須為需要申請證書的域名。","Obtaining certificate":"正在獲取證書,請稍等...","OK":"確定","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reloading nginx":"重载 Nginx","Reset":"重設","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","Table":"表格","Terminal":"終端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Updated at":"修改時間","Updated successfully":"已成功更新","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","License":{"Project":"開源軟體授權條款"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"Note: The server_name in the current configuration must be the domain name you need to get the certificate.","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}},"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Auto":"自动","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Comments":"注释","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Development Mode":"开发模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Domain Config Created Successfully":"域名配置文件创建成功","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","Next":"下一步","Nginx Log":"Nginx 日志","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:当前配置中的 server_name 必须为需要申请证书的域名。","Obtaining certificate":"正在获取证书","OK":"确定","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reloading nginx":"正在重载 Nginx","Reset":"重置","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","Table":"列表","Terminal":"终端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Updated at":"修改时间","Updated successfully":"更新成功","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","License":{"Project":"开源许可"}}} \ No newline at end of file diff --git a/frontend/src/language/zh_CN/app.mo b/frontend/src/language/zh_CN/app.mo index 096d9f8403895e989ef99f8e1abdb21325d98f93..214f2996f36b0f09cc67fff5b0c9a236cd2641f1 100644 GIT binary patch delta 3820 zcmaLZdr*{B9LDkEf*_`r1}0u`#k{2EwbH1_OO|P*p=LKTVi!TzOS0sZR>%a@gxHXZ z%Cc;9ri{|OgjQyw)-+ApRi~SlsLj;ab+QJh@AK}DrvB-S&wkE%-*?YB?|IL=xO&{7 z@sY1O#Md~=v!pAzxTSMnU&MrZhe02cnZ?7 z^P?u(3p?Ndya=zwWSoYr7~h5Lf+D0ZSB^~9)nX!UwBs+K2HuTV;{nt_@ytpSOv2uH zA!^_ZWA8F*P#X)j~d{1)ScdI=R?S1 zxCO}E+=I9VYf#@yXB6#?A!a6O!V{3OUADD@$*jMYD8vEHbO~yv5xcMq^(daOc0KC4 zeW(c?L?0fu_9v(t`5I^ASvw!36TL0@sQyBHXhNkCD!Ri8)Qqc91FT1N^gMRKH_W4` zNA^2*!xkN5OWhsyOm9H;rJIH7ZwYEe%TPD=Flyy$P}fCXunV@M2HuTY!o8@a{m?va z{)$?{1U7~yo{IWjI_meK4{G3HsDVbJR_Yei#P3Aic^)#Mh?_%&n{h>`j#i^)T!k87 z9ai9a%)m?7soIPI)OD*+9akZ%?dni>T95kvPSk|R^tE7us5@BOIo5Fvs=dM7jJlzE)DrJUP2f}WTVyDA2755ROJdZE zu|KM#NvJPOLk%1-SK9eacK&5^xB0I5srfBxWzL{h_AgZb`khz*i5StdOs1ll_CZ}R z+%Cwp_5@T%+18$px;}vFD2#faOYHns)H8n_^{C#l z<`C4KkFfR~sOxf29nZxyT!h+mwRZkFvmQ0!J?24Fe;?WT-%#WE(pZ0WoJ4Qh107NA zOw==+fVwaT`E7Ce<}%bXtU|5CX4G}N%(u(~s7Lz&Y68F5@f3EVuJ0P5q5*rNHrrs- zBbkDlz)aMI#i$>u6{uZZjarF1JHHXt&x__RTt<7pwa55l=O>xdQT;|{QPCaTX9r49 z6DYTKow)%uz-Dv1xeqmw53PL^)$vJGzdxdGoE>@AgkyaP)q!! zoj;2jP%m{~=!-3|K*uQTHSc|&>9yEXsDbtOWF>i=+(T4Cq(aYMyHrJwKtBp9dZz$DtDvyxKc4DsC z5^pA#lXCJ9QCUOsy&8`OA0}F@dr38!P3|VzBYF(YzHpmo%cVi|^^-m7x zgo_GQ&4^~UJMLRBduzAzuZfES>iAc$Dfz)UK{s`NASWCQ_;bSlRR8mp;)}kBKG5l0 z+|YqTqmk72qN6*PoL8~ybXnzhZ*FOPbXRn5=hS#_Mn^htOK9Bj%BhN1x31~(jxV9{ zwTD!nn0Bf~+(agJg}=1TiIU0_8~2>r^2W(MTcSJs=c1c>RKzAUIQ{MJI~z`Kc+AE6 dZLHmXx^|mutlQSOuD-Fn>cpz`(Wdm%e*+q%qwN3y delta 3551 zcmYk;c~Dhl7{~FK#V{1yaYMK$nwDaeskxzcgIqf}El zRyLzHsH2$USdNwbp)HyX;z_j~ZOkz0p{zi%2_ z;YgK4GVx`sb6;S|{ai?w8ah`Gzs3gm1Kx+fVGRC_&G07j&&4M=S07uV$^lHnZrB~O zF$2T?^RU}*6^>(o2j3xMaJNxoh)Hy=F(zO#rFu~O7mzG zSviDSnH8u3Zbl7oJF4DJ)E2zcjP=)zlUDI_)PTOiXuNFYE2tS(wji{MyL#skX>5Pp*wNr$=A9kzA=!Ffaj!RL8rpmA2-bZzK8nr^7 zqL%PF>I2k>qul|Up*}RdFdcI-I?B0KsP~Imf3?2}Rj!E0{#TLF4BkX7E{q1ctT8r^(QlyMTJ}PpfdtjO7o5 zX4nArVmDO19;k)~VG52youS$Ge6hI}HP9XAZd7}Fli7bY^f5Qo@C8))Thv}(wQ>`F zBHE%9RJ|U^FVXcivr$_#9kl{0QT0kp&)kLDy4O(yIMa^xSH)kg!XKys+(aF!7^bDI zcmOqkKBx~%4(iZOMXkV0R67e%?=Lmi<4Ve9R&K<}*7IbuOPGva?1>tAe=Cncbv)k6 zGtB~21B=WxW+`eQRaV}MYPTBIZVhSzXE7UpwCCZ61Aa%nP%n%$$D;P^Su0ORE%9t~ zEpj|um3b5&rTitTUVYYA15GnCP(RncsD84L35MNJKjU)k!CbQl)xdIdBWlmft^77> z#)nZ2opQ8rbA}NOJDniRYmDoTiY4wzL`nWZ?&GOHfKJ-6|oDP=uY7U|Q;XF^QC6qS%xGb{( zL&SJ1>&vNMic%MXZn5QQ1Ua=Y0NHxlEB zDa4CJC*l!e5~0)0hc1%xxa!N-gLsKpOtdE!5%Y)#36hSTbMqrt|B?-ziC)Aq|5oJM zm}@;kKf!54H{xyzT4plNBKlhSVRNALUQbvN74VW1gWiV3rOg-3nmZ$~WL7BO4bGVm z7#GS5Eh_TT8~s$>pmCp=>QT*7qP=-7O1#*l8(w_NVsA&wf8!@Cn2{F>&Isg%yaTPi zO)m--E)Et>E6AG{3@peigix@sC@^n+VK5NN&npPbF9>>DTHlGu%*gag+MM;Kv|XO` z>blzFHMOtRT&dX}>G+o|N9tA=dw1F%s;)`?FuHnO>Mv2={Ip{4R@yBuuER=iQ-@Ox zPVTQOKUPrvSrJ%kso?k#+EI~c2fvVr=3hnr%A~lq$#?0ciWkgNi&&AGtBh& z-FsGAxi0CQ{q}cW_dLGyecw6vz1tRbDV}4D)9%NO&(17Q3{X6g$ z@;`x}gFlBdwO>Mc??atm{QG|S7ohZOK$+(fcpF>}{}4U_Z->u8nP*7XCm>y^X2?`k z5Bvl?q02|0j5`BY!oP(w&LSoy^ScG!13wRC+&sunt>W(vxJBnfP}8}ai3-?2r z&lLOud=tv}@4~y_&!N1x=vIF{pM{dYQ}cc({XGI@9#2A9M=6wk5>VD%1Es(HP}*OB ze+2&;%Dmsz`G19?uiwBW@K%&4`uQr9cI%;l=bX|qMwUU#-D~V{+n|%xH<51@N z3}i^PMdvLj`Uydq=gUy$`CTaOnxO2%A)OzG((X+t^Z5b18NQ?Q{|sdvKZE7)H@e=U z6Y-NWDE)=_lljy`Szim3`R<3({{WPJhTs?BRn4D5*{@&2KZQ5_fv@K;L)p)#ASS6^ zg3{m1Q1saZWnJx1^wtHX-AP@45z4qTQ1tgbD0=;o=D%tF3W{Dnj#0?G?||~&T~Ok} zy->z|7|J+LLebN+Q0DzjDC;hPGM@^_Qd9y;Kdn&a+X;nCk%}D#p|slr zrQc47s#PD9e#fD_e+kNbz6Zt5eyHpJ6Usb(4ex~?LecXQlrH1y+fc^;vF7`bq0}#+^m_|~%6jgH($BL{+CLA!1TD>7 zy8gJXKdm{b`IhECYQ6_$9{&MlA8sP3OaHe)>HiKW`*;tOc|NA=^L71ZoqrLEeuFw6 zfzo~llzw)@W$-m!e+9~ZzXfGoKh)*Ff-;ZaLZ+lXjq%F+OQFo`5zUoQ^s+|hEhz0m zQ2MQgqL&6J_BN>NM>VIR%=ZVH{{*GK_jJ9yEaQC!O24;5+5bCrJ|BwSwn1qZf`k+m z(`ldJ@12}heNu42ueR^G%vv&2DC4itd|dMxDD9uu+z!2c*Y&UJ@)pfb_%`i(;N9?B z{D~hmKNgQojv~f4m5n z!bW%#v=MnQGtbXUy_{0tfikX~A-j=YXbCbvPq4MF2I-LvGA+PDYoM-Ei9%LU0eU|4K@(R)?8U1j)dG?UWKco}OAtvKJ z5A)xl(-PCaiNuj7blC%%f@+=K3Y&CV5Yy?y@Xrz4$a|vvi~YTXeAg>c>OnYwbRsK| zRmgLQ#JQJ|)yUJx5kzcTo&d59c?@|R`AbCXIrID#iJNss?E24;Cy@Vlks2QW_&2w=?*g-u#63nAepFTR7Vm*HY==}g)OY`|8B6_ z43sPRGoFrASfpZ>VTb9W!dC?acEDf%YBL@vlcZfztyU-OP|&Ed<7H~i=B-9y+>9q; zlFU{a1Nyv&N~Y|t=ujU6sE0wJ50Mu{1)LpDpWVn%>r z6JeP)=He}oeY1=;tBjZx-9bNV&1gA)v9jWb84Z$(o5iBFrJE|{6*IIPgD5c*p?IDV z)RoKBTF*u_jQq8EY>^$T$rQw}HYpNr_qT4XwFAqn6dm~bpEFrCmx__}cHJ;BjyY2( zG41OOLAPVR88e9`Jntw;ghJI)T5jZTQfng>rX4nXl^ebWgGOO?({({RF7{QUywrl- z@ryjySw}}9W9fa%)H=`XjG}_VO!9Y4R=?pdL%$Tv5dX`X__}Z)T3s18s;pwsoxfoP zR{Y+Wp{vxoXcUj|g1|a4IDco^H&5ei5q?5NBpO%ieZ`4SYrQUcr6N{ZlU3n65em4j zywr*tfh_yZcB1uchp{mdH`YfI;h-WL$B@?BVLMia`9FmRGb<~T5X-EL+B+yR%B^b8 zp`%u*9pf#jGXnwoiPJnDm%P|#*3iq1%8(@%S!LSs+}vE{d3Js{7B@p7rMXax`FKpU z!V20lBpUhG^CaXhlCK02k)DHXqSzSv3p*_1~gIR8o*Fm{V#trC@!3<3! ziX%l)M`bj!(^qD0l@$u*l!qf#VI7Yn(Q1k0PZt$!UQ>peEM~eHi!heX`SN2c9({0` zQEU+#ErZ>@k?M2R1~bfxv;)O5S@DRu%vJ&k8P0@gwT5Aa@v?YCw4ro_^`U!GUfA1c z#j7GjA5AZ;Vik5EHdj;>VV5}|0v2c6b)|(C#<$Vh8CM%o?M?$#s*MqT8N-y+HVM8Q zin2`EaNj?uAy(p+2lCd>>IxwuEb0@ucOAg z9EnAD-k_#ZcXOk<1S^#ZQx~;LELIq>Bw1;CP8hOEG3o3TGplH%%q}K8dZsQ@k48{w zW)#s^kZqrD=iMAKF03uhkb$MiOI%PE71#kQ9Fu{)yisJC6>5uR24npDo4h3}G$0h}dOw@G7y-tU%}m9x*R%epPlTBo-McvjXL;K;lBRQHF^u_Z%=&@7<`Vw@VE6 zQZ6dRmK8SeSFvU@Y^)$1j+YrRTP}yRsiIBD#NKT$EarMMDIw~679TLfVaxzy5sUT= zz9bUj)+t+rsYJ~H;nxeVfg11CjO`g5T=Uiw!+-)2d@T@{R@{TOR*HLicbZIc!A@=E zN>X9vsjb?U=MtW~Y-RqXUd(%Nh0MbbdlDyi*gT1mQPF zJS@)$N5a-zS)TE7+4iF67H`Pkux@^|6}b;CUgO_2bBd}fiH~t&>jRY`Hu-DbzT$RY z-&(Xj=h69gG7*AF4wn-y(&5rP<52>};>;Bwn6tV%&*1c~mJ^2V7C)b(>tybmBb?E3 ze>OPkCpcwahk`|C%e-}>y$Gv<@TRV4exR5#&kw6&~3S# zZt9r5HtHU@tlZaIo#`oQj886TwrRmmuj8bRz)g#rq%7OPj|nj{2FI;&~3h$JTvBYU!J{sE!Et#W|iCD?zHwY z_jK){*=xs?J9#eEGNGJZwW(vn$-W_#I^X1W_c~K&jHOP;Si0`g2QzKyqn)YYk?b!Q zf76wZtS=Y8z_*$YW)3a*c1d@)CVOWxI@VU_<0H1#89L{7^{C{@I(ApXZSHjT45;Ms zy5!)1e4#i41L(_FoZF2(U-UJQX*fBYni&(*s8LBT?Kjn#jFC57NRFQKf}pk~`8xRs zv(i)ZTP(=vw=%vidU;~4I7f{5R_Z`2q`>P%~LxIH=2B3~C7 z9~*5+9Y0LB0<8^vDEY=A|F!hd{bCZQ2Jo`%4++2ApLa%yUA@UuQ(~k;n0$N2J13{a ze3R#=lNZjVCXS|NT5kB=knEjy8c!%6nI0)?n$nrM_4tE2E$w zXfxhqWPdRv`$p4kyPS@8r*q%z^l^y~&Eq%vbjbLU_vN7dIyrib7nE-jIx~Ca8U~-L zZPfYH@IiO?#q^m2gbAH;_P04B2c2CLN^8T1wrw3i=rlDsCVc}@(r_~Ys})7L7wQOe zWcE1q=jSr5#1nVqg#H@P2S_HMwOmE@5<-vGaehbuLs7|H$B16@HtL=qc6W8){mCxe zPAVFd z=)ZHl2|67OZWks!wmUgEqv1I>dT_4pQ!?1hC9Fb@twX!gp7(z+Q+IuZ-@y$k=61-} zwAW&IgmY23Q{7H|FFw!LKqk_htaC>Ou`;>qqYQtm| zCNn%ju%EzgH1zS0kyDm&2Cso1jxwR-1`Tv;0*Cur6Gw_RB{e(4$=XfG3)j>V`olF6a8jiK(N!5#nA^IcTU#3NBXg-*~_iizB{p>vwgn*Gp$ZzGZ!jU z_I_=fbM?q|=R$V8e!sR|te*hQqH()a!xg8k(dj%hJADENc1C)f#s<*@p9lVC)6Q+~ z_U(xmh|;)@a)!E7uh+W6$Gy9ocd5zT5+*17Ep+?d@a|Xxld><~6(SFR(*elW`Sp3v zmHalDuLZYlpUa8T(K&mykHDo;BPX4GdvLuo*lLsZZ0`i22*;E2n;XYm-GWm0;22)1 mIH+(M-&WFnyPeKvoX0=9vV)153ntm6hW{S_?!mn}9{dm229?|Z literal 0 HcmV?d00001 diff --git a/frontend/src/language/zh_TW/app.po b/frontend/src/language/zh_TW/app.po index 247037de6..4719d4264 100644 --- a/frontend/src/language/zh_TW/app.po +++ b/frontend/src/language/zh_TW/app.po @@ -11,25 +11,25 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: easygettext\n" -"X-Generator: Poedit 2.2\n" +"X-Generator: Poedit 3.2.2\n" -#: src/routes/index.ts:116 +#: src/routes/index.ts:125 msgid "About" msgstr "關於" -#: src/routes/index.ts:99 src/views/domain/ngx_conf/LogEntry.vue:64 +#: src/routes/index.ts:100 src/views/domain/ngx_conf/LogEntry.vue:64 msgid "Access Logs" -msgstr "" +msgstr "訪問日誌" -#: src/views/config/Config.vue:24 src/views/domain/DomainList.vue:42 +#: src/views/config/Config.vue:24 src/views/domain/DomainList.vue:47 #: src/views/user/User.vue:43 msgid "Action" msgstr "操作" -#: src/components/StdDataDisplay/StdCurd.vue:134 -#: src/components/StdDataDisplay/StdCurd.vue:26 +#: src/components/StdDataDisplay/StdCurd.vue:145 +#: src/components/StdDataDisplay/StdCurd.vue:25 msgid "Add" -msgstr "" +msgstr "新增" #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:31 #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32 @@ -37,68 +37,80 @@ msgstr "" msgid "Add Directive Below" msgstr "在下面新增指令" -#: src/views/domain/ngx_conf/LocationEditor.vue:33 -#: src/views/domain/ngx_conf/LocationEditor.vue:48 +#: src/views/domain/ngx_conf/LocationEditor.vue:45 +#: src/views/domain/ngx_conf/LocationEditor.vue:50 +#: src/views/domain/ngx_conf/LocationEditor.vue:51 +#: src/views/domain/ngx_conf/LocationEditor.vue:60 msgid "Add Location" msgstr "新增 Location" -#: src/routes/index.ts:55 src/views/domain/DomainAdd.vue:2 +#: src/routes/index.ts:56 src/views/domain/DomainAdd.vue:2 msgid "Add Site" msgstr "新增站點" -#: src/views/domain/DomainEdit.vue:19 +#: src/views/domain/DomainEdit.vue:18 src/views/domain/DomainEdit.vue:19 msgid "Advance Mode" msgstr "高階模式" -#: src/components/StdDataDisplay/StdTable.vue:44 -#: src/views/domain/DomainList.vue:27 -#, fuzzy -msgid "Are you sure you want to delete ?" -msgstr "您确定要删除?" +#: src/components/StdDataDisplay/StdTable.vue:54 +#: src/views/domain/DomainList.vue:26 +msgid "Are you sure you want to delete?" +msgstr "你確定你要刪除?" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:15 +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:27 msgid "Are you sure you want to remove this directive?" msgstr "您確定要刪除這條指令?" -#: src/views/domain/ngx_conf/LocationEditor.vue:9 -#, fuzzy +#: src/views/domain/ngx_conf/LocationEditor.vue:19 msgid "Are you sure you want to remove this location?" -msgstr "您確定要刪除這條指令?" +msgstr "您確定要刪除此 Location 嗎?" + +#: src/views/preference/Preference.vue:7 src/views/preference/Preference.vue:8 +msgid "Auto" +msgstr "自動" #: src/views/nginx_log/NginxLog.vue:4 msgid "Auto Refresh" -msgstr "" +msgstr "自動刷新" -#: src/views/domain/cert/IssueCert.vue:78 +#: src/views/domain/cert/IssueCert.vue:72 msgid "Auto-renewal disabled for %{name}" msgstr "已關閉 %{name} 自動續簽" -#: src/views/domain/cert/IssueCert.vue:72 +#: src/views/domain/cert/IssueCert.vue:66 msgid "Auto-renewal enabled for %{name}" msgstr "已啟用 %{name} 自動續簽" -#: src/views/domain/DomainEdit.vue:178 src/views/nginx_log/NginxLog.vue:172 +#: src/views/domain/DomainEdit.vue:187 src/views/nginx_log/NginxLog.vue:173 msgid "Back" msgstr "返回" #: src/views/other/Error.vue:12 -#, fuzzy msgid "Back Home" -msgstr "返回" +msgstr "回到首頁" #: src/views/domain/DomainAdd.vue:5 msgid "Base information" msgstr "基本訊息" -#: src/views/domain/DomainEdit.vue:22 +#: src/views/domain/DomainEdit.vue:21 src/views/domain/DomainEdit.vue:22 msgid "Basic Mode" msgstr "基本模式" +#: src/components/StdDataDisplay/StdBatchEdit.vue:5 +#: src/components/StdDataDisplay/StdTable.vue:12 +#: src/components/StdDataDisplay/StdTable.vue:13 +#: src/components/StdDataDisplay/StdTable.vue:18 +msgid "Batch Modify" +msgstr "批量修改" + #: src/views/other/About.vue:21 msgid "Build with" msgstr "構建基於" -#: src/components/StdDataDisplay/StdCurd.vue:28 +#: src/components/StdDataDisplay/StdBatchEdit.vue:7 +#: src/components/StdDataDisplay/StdCurd.vue:27 +#: src/components/StdDataEntry/components/StdSelector.vue:11 #: src/components/StdDataEntry/compontents/StdSelector.vue:11 #: src/views/config/ConfigEdit.vue:49 msgid "Cancel" @@ -116,9 +128,9 @@ msgstr "此憑證有效" msgid "Certificate Status" msgstr "憑證狀態" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29 -#: src/views/domain/ngx_conf/LocationEditor.vue:21 -#: src/views/domain/ngx_conf/LocationEditor.vue:35 +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:41 +#: src/views/domain/ngx_conf/LocationEditor.vue:31 +#: src/views/domain/ngx_conf/LocationEditor.vue:47 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 msgid "Comments" msgstr "註釋" @@ -135,8 +147,8 @@ msgstr "配置" msgid "Configure SSL" msgstr "配置 SSL" -#: src/views/domain/ngx_conf/LocationEditor.vue:27 -#: src/views/domain/ngx_conf/LocationEditor.vue:41 +#: src/views/domain/ngx_conf/LocationEditor.vue:37 +#: src/views/domain/ngx_conf/LocationEditor.vue:53 msgid "Content" msgstr "內容" @@ -158,9 +170,14 @@ msgstr "建立時間" #: src/language/constants.ts:13 msgid "Creating client facilitates communication with the CA server" -msgstr "" +msgstr "創建客戶端方便與CA服務器通信" -#: src/routes/index.ts:27 +#: src/views/preference/Preference.vue:13 +#: src/views/preference/Preference.vue:14 +msgid "Dark" +msgstr "深色" + +#: src/routes/index.ts:28 msgid "Dashboard" msgstr "儀表盤" @@ -168,19 +185,18 @@ msgstr "儀表盤" msgid "Database (Optional, default: database)" msgstr "資料庫 (可選,預設: database)" -#: src/components/StdDataDisplay/StdTable.vue:366 -#: src/views/domain/DomainList.vue:111 +#: src/components/StdDataDisplay/StdTable.vue:527 +#: src/views/domain/DomainList.vue:115 msgid "Delete" -msgstr "" +msgstr "刪除" -#: src/components/StdDataDisplay/StdTable.vue:120 +#: src/components/StdDataDisplay/StdTable.vue:132 msgid "Delete ID: %{id}" msgstr "刪除 ID: %{id}" -#: src/views/domain/DomainList.vue:76 -#, fuzzy +#: src/views/domain/DomainList.vue:81 msgid "Delete site: %{site_name}" -msgstr "刪除 ID: %{id}" +msgstr "刪除站點:%{site_name}" #: src/views/other/About.vue:7 src/views/other/About.vue:8 msgid "Development Mode" @@ -190,20 +206,23 @@ msgstr "開發模式" msgid "Directive" msgstr "指令" +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:1 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:2 msgid "Directives" msgstr "指令" -#: src/views/domain/cert/IssueCert.vue:80 +#: src/views/domain/cert/IssueCert.vue:74 msgid "Disable auto-renewal failed for %{name}" msgstr "關閉 %{name} 自動續簽失敗" -#: src/views/domain/DomainEdit.vue:10 src/views/domain/DomainList.vue:17 -#: src/views/domain/DomainList.vue:29 +#: src/views/domain/DomainEdit.vue:10 src/views/domain/DomainEdit.vue:9 +#: src/views/domain/DomainList.vue:16 src/views/domain/DomainList.vue:34 +#: src/views/domain/DomainList.vue:7 src/views/domain/DomainList.vue:8 +#: src/views/domain/DomainList.vue:9 msgid "Disabled" msgstr "禁用" -#: src/views/domain/DomainEdit.vue:112 src/views/domain/DomainList.vue:64 +#: src/views/domain/DomainEdit.vue:118 src/views/domain/DomainList.vue:69 msgid "Disabled successfully" msgstr "禁用成功" @@ -215,15 +234,15 @@ msgstr "磁碟 IO" msgid "Domain Config Created Successfully" msgstr "域名配置文件創建成功" -#: src/views/domain/DomainEdit.vue:5 +#: src/views/domain/DomainEdit.vue:4 src/views/domain/DomainEdit.vue:5 msgid "Edit %{n}" msgstr "編輯 %{n}" -#: src/routes/index.ts:77 src/views/config/ConfigEdit.vue:2 +#: src/routes/index.ts:78 src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "編輯配置" -#: src/routes/index.ts:59 +#: src/routes/index.ts:60 msgid "Edit Site" msgstr "編輯站點" @@ -231,7 +250,7 @@ msgstr "編輯站點" msgid "Email (*)" msgstr "郵箱 (*)" -#: src/views/domain/cert/IssueCert.vue:74 +#: src/views/domain/cert/IssueCert.vue:68 msgid "Enable auto-renewal failed for %{name}" msgstr "啟用 %{name} 自動續簽失敗" @@ -243,14 +262,15 @@ msgstr "啟用失敗" msgid "Enable TLS" msgstr "啟用 TLS" -#: src/views/domain/DomainEdit.vue:33 src/views/domain/DomainEdit.vue:7 -#: src/views/domain/DomainList.vue:12 src/views/domain/DomainList.vue:20 -#: src/views/domain/DomainList.vue:26 +#: src/views/domain/DomainEdit.vue:33 src/views/domain/DomainEdit.vue:6 +#: src/views/domain/DomainEdit.vue:7 src/views/domain/DomainList.vue:10 +#: src/views/domain/DomainList.vue:11 src/views/domain/DomainList.vue:12 +#: src/views/domain/DomainList.vue:19 src/views/domain/DomainList.vue:31 msgid "Enabled" msgstr "啟用" -#: src/views/domain/DomainAdd.vue:46 src/views/domain/DomainEdit.vue:103 -#: src/views/domain/DomainList.vue:54 +#: src/views/domain/DomainAdd.vue:46 src/views/domain/DomainEdit.vue:109 +#: src/views/domain/DomainList.vue:59 msgid "Enabled successfully" msgstr "啟用成功" @@ -258,30 +278,32 @@ msgstr "啟用成功" msgid "Encrypt website with Let's Encrypt" msgstr "用 Let's Encrypt 對網站進行加密" -#: src/routes/index.ts:103 src/views/domain/ngx_conf/LogEntry.vue:68 +#: src/routes/index.ts:104 src/views/domain/ngx_conf/LogEntry.vue:68 msgid "Error Logs" -msgstr "" +msgstr "錯誤日志" #: src/views/domain/cert/CertInfo.vue:17 msgid "Expiration Date: %{date}" msgstr "過期時間: %{date}" #: src/components/StdDataDisplay/StdTable.vue:12 -#: src/components/StdDataDisplay/StdTable.vue:317 +#: src/components/StdDataDisplay/StdTable.vue:362 +#: src/components/StdDataDisplay/StdTable.vue:6 +#: src/components/StdDataDisplay/StdTable.vue:7 msgid "Export" -msgstr "" +msgstr "導出" -#: src/views/domain/DomainEdit.vue:115 src/views/domain/DomainList.vue:68 +#: src/views/domain/DomainEdit.vue:121 src/views/domain/DomainList.vue:73 msgid "Failed to disable %{msg}" msgstr "禁用失敗 %{msg}" -#: src/views/domain/DomainEdit.vue:106 src/views/domain/DomainList.vue:58 +#: src/views/domain/DomainEdit.vue:112 src/views/domain/DomainList.vue:63 msgid "Failed to enable %{msg}" msgstr "啟用失敗 %{msg}" #: src/language/constants.ts:9 msgid "Failed to get certificate information" -msgstr "" +msgstr "獲取證書信息失敗" #: src/views/other/Error.vue:3 src/views/other/Error.vue:4 msgid "File Not Found" @@ -289,63 +311,69 @@ msgstr "未找到檔案" #: src/views/nginx_log/NginxLog.vue:7 msgid "Filter" -msgstr "" +msgstr "篩選" #: src/language/constants.ts:20 src/views/domain/DomainAdd.vue:7 msgid "Finished" msgstr "完成" +#: src/components/StdDataEntry/components/StdPassword.vue:42 #: src/components/StdDataEntry/compontents/StdPassword.vue:42 msgid "Generate" -msgstr "" +msgstr "生成" #: src/language/constants.ts:11 msgid "Generating private key for registering account" -msgstr "" +msgstr "生成註冊賬號私鑰" -#: src/views/domain/cert/IssueCert.vue:103 +#: src/views/domain/cert/IssueCert.vue:97 msgid "Getting the certificate, please wait..." msgstr "正在獲取憑證,請稍等..." -#: src/routes/index.ts:20 +#: src/routes/index.ts:21 msgid "Home" msgstr "首頁" -#: src/routes/index.ts:126 src/views/other/Install.vue:128 +#: src/routes/index.ts:135 src/views/other/Install.vue:128 msgid "Install" msgstr "安裝" #: src/views/other/Install.vue:68 -#, fuzzy msgid "Install successfully" -msgstr "啟用成功" +msgstr "安裝成功" #: src/views/domain/cert/CertInfo.vue:15 msgid "Intermediate Certification Authorities: %{issuer}" msgstr "中級憑證頒發機構: %{issuer}" #: src/language/constants.ts:21 -#, fuzzy msgid "Issued certificate successfully" -msgstr "啟用成功" +msgstr "頒發證書成功" #: src/views/user/User.vue:26 msgid "Leave blank for no change" msgstr "留空表示不修改" +#: src/views/preference/Preference.vue:10 +#: src/views/preference/Preference.vue:11 +msgid "Light" +msgstr "淺色" + #: src/views/dashboard/DashBoard.vue:141 msgid "Load Averages:" msgstr "系統負載:" -#: src/views/domain/ngx_conf/LocationEditor.vue:5 +#: src/views/domain/ngx_conf/LocationEditor.vue:15 +#: src/views/domain/ngx_conf/LocationEditor.vue:8 +#: src/views/domain/ngx_conf/LocationEditor.vue:9 msgid "Location" msgstr "Location" -#: src/views/domain/ngx_conf/LocationEditor.vue:39 +#: src/views/domain/ngx_conf/LocationEditor.vue:40 msgid "Locations" msgstr "Locations" -#: src/routes/index.ts:132 src/views/other/Login.vue:103 +#: src/routes/index.ts:141 src/views/other/Login.vue:103 msgid "Login" msgstr "登入" @@ -357,24 +385,23 @@ msgstr "登入成功" msgid "Logout successful" msgstr "登出成功" -#: src/views/domain/cert/IssueCert.vue:226 -#, fuzzy +#: src/views/domain/cert/IssueCert.vue:209 msgid "" "Make sure you have configured a reverse proxy for .well-known directory to " "HTTPChallengePort (default: 9180) before getting the certificate." msgstr "" -"在獲取憑證前,請確保配置檔案中已將 .well-known 目錄反向代理到 " +"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 " "HTTPChallengePort (預設: 9180)" -#: src/routes/index.ts:68 +#: src/routes/index.ts:69 msgid "Manage Configs" msgstr "配置管理" -#: src/routes/index.ts:43 src/views/domain/DomainList.vue:2 +#: src/routes/index.ts:44 src/views/domain/DomainList.vue:2 msgid "Manage Sites" msgstr "網站管理" -#: src/routes/index.ts:35 src/views/user/User.vue:2 +#: src/routes/index.ts:36 src/views/user/User.vue:2 msgid "Manage Users" msgstr "使用者管理" @@ -386,21 +413,21 @@ msgstr "記憶體" msgid "Memory and Storage" msgstr "記憶體和存儲" -#: src/components/StdDataDisplay/StdCurd.vue:26 -#: src/components/StdDataDisplay/StdTable.vue:18 -#: src/components/StdDataDisplay/StdTable.vue:19 -#: src/components/StdDataDisplay/StdTable.vue:24 -#: src/components/StdDataDisplay/StdTable.vue:34 -#: src/components/StdDataDisplay/StdTable.vue:36 -#, fuzzy +#: src/components/StdDataDisplay/StdCurd.vue:25 +#: src/components/StdDataDisplay/StdTable.vue:25 +#: src/components/StdDataDisplay/StdTable.vue:26 +#: src/components/StdDataDisplay/StdTable.vue:31 +#: src/components/StdDataDisplay/StdTable.vue:44 +#: src/components/StdDataDisplay/StdTable.vue:46 msgid "Modify" -msgstr "修改配置" +msgstr "修改" #: src/views/domain/DomainAdd.vue:147 msgid "Modify Config" msgstr "修改配置" -#: src/views/config/Config.vue:12 src/views/domain/DomainList.vue:14 +#: src/views/config/Config.vue:12 src/views/domain/DomainEdit.vue:36 +#: src/views/domain/DomainList.vue:15 msgid "Name" msgstr "名稱" @@ -424,18 +451,18 @@ msgstr "上傳流量" msgid "Next" msgstr "下一步" -#: src/routes/index.ts:93 src/views/nginx_log/NginxLog.vue:2 +#: src/routes/index.ts:94 src/views/nginx_log/NginxLog.vue:2 msgid "Nginx Log" -msgstr "" +msgstr "Nginx 日誌" -#: src/components/StdDataDisplay/StdTable.vue:42 -#: src/views/domain/DomainList.vue:25 -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:17 -#: src/views/domain/ngx_conf/LocationEditor.vue:11 +#: src/components/StdDataDisplay/StdTable.vue:52 +#: src/views/domain/DomainList.vue:24 +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29 +#: src/views/domain/ngx_conf/LocationEditor.vue:21 msgid "No" msgstr "取消" -#: src/routes/index.ts:138 src/routes/index.ts:140 +#: src/routes/index.ts:147 src/routes/index.ts:149 msgid "Not Found" msgstr "找不到頁面" @@ -443,21 +470,22 @@ msgstr "找不到頁面" msgid "Not Valid Before: %{date}" msgstr "此前無效: %{date}" -#: src/views/domain/cert/IssueCert.vue:218 -#, fuzzy +#: src/views/domain/cert/IssueCert.vue:201 msgid "" "Note: The server_name in the current configuration must be the domain name " "you need to get the certificate." -msgstr "注意:當前配置中的 server_name 必須為需要申請憑證的域名。" +msgstr "注意:當前配置中的 server_name 必須為需要申請證書的域名。" #: src/language/constants.ts:16 src/views/domain/cert/IssueCert.vue:3 msgid "Obtaining certificate" -msgstr "" +msgstr "正在獲取證書,請稍等..." -#: src/components/StdDataDisplay/StdCurd.vue:29 -#: src/components/StdDataDisplay/StdTable.vue:43 +#: src/components/StdDataDisplay/StdBatchEdit.vue:8 +#: src/components/StdDataDisplay/StdCurd.vue:28 +#: src/components/StdDataDisplay/StdTable.vue:53 +#: src/components/StdDataEntry/components/StdSelector.vue:12 #: src/components/StdDataEntry/compontents/StdSelector.vue:12 -#: src/views/domain/DomainList.vue:26 +#: src/views/domain/DomainList.vue:25 msgid "OK" msgstr "確定" @@ -477,8 +505,8 @@ msgstr "密碼" msgid "Password (*)" msgstr "密碼 (*)" -#: src/views/domain/ngx_conf/LocationEditor.vue:24 -#: src/views/domain/ngx_conf/LocationEditor.vue:38 +#: src/views/domain/ngx_conf/LocationEditor.vue:34 +#: src/views/domain/ngx_conf/LocationEditor.vue:50 msgid "Path" msgstr "路徑" @@ -494,18 +522,21 @@ msgstr "請輸入您的密碼!" msgid "Please input your username!" msgstr "請輸入您的使用者名稱!" +#: src/routes/index.ts:117 src/views/preference/Preference.vue:2 +msgid "Preference" +msgstr "設定" + #: src/language/constants.ts:12 -#, fuzzy msgid "Preparing lego configurations" -msgstr "配置" +msgstr "準備 Lego 配置" #: src/language/constants.ts:7 msgid "Prohibit changing root password in demo" -msgstr "" +msgstr "禁止在demo中修改root密碼" #: src/language/constants.ts:8 msgid "Prohibit deleting the default user" -msgstr "" +msgstr "禁止刪除默認用戶" #: src/views/other/About.vue:19 msgid "Project Team" @@ -521,17 +552,21 @@ msgstr "下載" #: src/language/constants.ts:15 msgid "Registering user" -msgstr "" +msgstr "註冊用戶" #: src/language/constants.ts:19 msgid "Reloading nginx" -msgstr "" +msgstr "重载 Nginx" +#: src/components/StdDataDisplay/StdTable.vue:10 #: src/components/StdDataDisplay/StdTable.vue:15 +#: src/components/StdDataDisplay/StdTable.vue:9 msgid "Reset" -msgstr "" +msgstr "重設" -#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:181 +#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:190 +#: src/views/preference/Preference.vue:22 +#: src/views/preference/Preference.vue:23 msgid "Save" msgstr "儲存" @@ -545,29 +580,35 @@ msgstr "儲存指令" msgid "Save error %{msg}" msgstr "儲存錯誤 %{msg}" -#: src/components/StdDataDisplay/StdCurd.vue:102 -#, fuzzy +#: src/components/StdDataDisplay/StdBatchEdit.vue:40 +msgid "Save successfully" +msgstr "保存成功" + +#: src/components/StdDataDisplay/StdCurd.vue:108 msgid "Save Successfully" -msgstr "儲存成功" +msgstr "保存成功" #: src/views/config/ConfigEdit.vue:34 src/views/domain/DomainAdd.vue:43 -#: src/views/domain/DomainEdit.vue:91 +#: src/views/domain/DomainEdit.vue:97 msgid "Saved successfully" msgstr "儲存成功" +#: src/components/StdDataEntry/components/StdSelector.vue:13 #: src/components/StdDataEntry/compontents/StdSelector.vue:13 msgid "Selector" -msgstr "" +msgstr "選擇器" #: src/views/dashboard/DashBoard.vue:21 src/views/dashboard/DashBoard.vue:85 msgid "Send" msgstr "上傳" -#: src/components/StdDataDisplay/StdTable.vue:140 -#: src/components/StdDataDisplay/StdTable.vue:298 -#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:56 -#: src/views/domain/DomainEdit.vue:68 src/views/domain/DomainEdit.vue:77 -#: src/views/domain/DomainEdit.vue:94 src/views/domain/DomainList.vue:78 +#: src/components/StdDataDisplay/StdBatchEdit.vue:43 +#: src/components/StdDataDisplay/StdTable.vue:168 +#: src/components/StdDataDisplay/StdTable.vue:343 +#: src/components/StdDataDisplay/StdTable.vue:463 +#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:100 +#: src/views/domain/DomainEdit.vue:62 src/views/domain/DomainEdit.vue:74 +#: src/views/domain/DomainEdit.vue:83 src/views/domain/DomainList.vue:83 #: src/views/other/Install.vue:71 msgid "Server error" msgstr "伺服器錯誤" @@ -580,29 +621,24 @@ msgstr "伺服器資訊" msgid "server_name not found in directives" msgstr "未在指令集合中找到 server_name" -#: src/views/domain/cert/IssueCert.vue:209 src/views/domain/DomainAdd.vue:112 +#: src/views/domain/cert/IssueCert.vue:195 src/views/domain/DomainAdd.vue:112 msgid "server_name parameter is required" msgstr "必須為 server_name 指令指明參數" -#: src/views/domain/cert/IssueCert.vue:212 -#: src/views/domain/cert/IssueCert.vue:35 -msgid "server_name parameters more than one" -msgstr "server_name 指令包含多個參數" - +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:6 #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:7 msgid "Single Directive" msgstr "單行指令" -#: src/routes/index.ts:107 -#, fuzzy +#: src/routes/index.ts:108 msgid "Site Logs" -msgstr "站點列表" +msgstr "網站日誌" -#: src/routes/index.ts:51 +#: src/routes/index.ts:52 msgid "Sites List" msgstr "站點列表" -#: src/views/domain/DomainList.vue:19 +#: src/views/domain/DomainList.vue:24 msgid "Status" msgstr "狀態" @@ -619,22 +655,20 @@ msgid "Swap" msgstr "交換空間" #: src/components/StdDataDisplay/StdCurd.vue:3 -#, fuzzy msgid "Table" -msgstr "啟用" +msgstr "表格" -#: src/routes/index.ts:85 src/views/pty/Terminal.vue:2 +#: src/routes/index.ts:86 src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "終端" -#: src/views/domain/cert/IssueCert.vue:222 -#, fuzzy +#: src/views/domain/cert/IssueCert.vue:205 msgid "" "The certificate for the domain will be checked every hour, and will be " "renewed if it has been more than 1 month since it was last issued." msgstr "" -"系統將會每小時檢測一次該域名憑證,若距離上次簽發已超過1個月,則將自動續簽。" -"
如果您之前沒有憑證,請先點選「從 Let's Encrypt 獲取憑證」。" +"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。" +"
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。" #: src/views/other/Install.vue:54 msgid "The filename cannot contain the following characters: %{c}" @@ -642,13 +676,21 @@ msgstr "檔名不能包含以下字元: %{c}" #: src/language/constants.ts:6 msgid "The username or password is incorrect" -msgstr "" +msgstr "用戶名或密碼不正確" + +#: src/views/preference/Preference.vue:5 +msgid "Theme" +msgstr "外觀樣式" -#: src/views/config/Config.vue:17 src/views/domain/DomainList.vue:36 +#: src/views/config/Config.vue:17 src/views/domain/DomainList.vue:41 #: src/views/user/User.vue:37 msgid "Updated at" msgstr "修改時間" +#: src/components/StdDataDisplay/StdTable.vue:461 +msgid "Updated successfully" +msgstr "已成功更新" + #: src/views/dashboard/DashBoard.vue:137 msgid "Uptime:" msgstr "執行時間:" @@ -663,7 +705,7 @@ msgstr "使用者名稱 (*)" #: src/language/constants.ts:14 msgid "Using HTTP01 challenge provider" -msgstr "" +msgstr "使用 HTTP01 挑戰提供者" #: src/views/domain/cert/IssueCert.vue:26 src/views/domain/DomainAdd.vue:24 msgid "Warning" @@ -676,14 +718,14 @@ msgstr "寫" #: src/language/constants.ts:18 msgid "Writing certificate private key to disk" -msgstr "" +msgstr "將證書私鑰寫入磁盤" #: src/language/constants.ts:17 msgid "Writing certificate to disk" -msgstr "" +msgstr "將證書寫入磁盤" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:16 -#: src/views/domain/ngx_conf/LocationEditor.vue:10 +#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:28 +#: src/views/domain/ngx_conf/LocationEditor.vue:20 msgid "Yes" msgstr "是的" @@ -692,6 +734,13 @@ msgctxt "Project" msgid "License" msgstr "開源軟體授權條款" +#, fuzzy +#~ msgid "Are you sure you want to delete ?" +#~ msgstr "您确定要删除?" + +#~ msgid "server_name parameters more than one" +#~ msgstr "server_name 指令包含多個參數" + #~ msgid "404 Not Found" #~ msgstr "404 未找到頁面" diff --git a/frontend/src/layouts/BaseLayout.vue b/frontend/src/layouts/BaseLayout.vue index 729f1b51a..d5aaa51d2 100644 --- a/frontend/src/layouts/BaseLayout.vue +++ b/frontend/src/layouts/BaseLayout.vue @@ -122,37 +122,36 @@ const lang = computed(() => { diff --git a/frontend/version.json b/frontend/version.json index 006b322ef..7421b2306 100644 --- a/frontend/version.json +++ b/frontend/version.json @@ -1 +1 @@ -{"version":"1.6.8","build_id":57,"total_build":127} \ No newline at end of file +{"version":"1.7.0","build_id":61,"total_build":131} \ No newline at end of file From 1e304fa4a3ecb36cf1c4348e9a2ac8be43bfac5b Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Mon, 2 Jan 2023 13:28:19 +0800 Subject: [PATCH 06/22] feat: support custom CADirURL #16 --- frontend/src/version.json | 2 +- frontend/src/views/preference/Preference.vue | 1 - frontend/version.json | 2 +- server/pkg/cert/cert.go | 4 ++++ server/settings/settings.go | 2 ++ 5 files changed, 8 insertions(+), 3 deletions(-) diff --git a/frontend/src/version.json b/frontend/src/version.json index 7421b2306..75a1ec37d 100644 --- a/frontend/src/version.json +++ b/frontend/src/version.json @@ -1 +1 @@ -{"version":"1.7.0","build_id":61,"total_build":131} \ No newline at end of file +{"version":"1.7.0","build_id":62,"total_build":132} \ No newline at end of file diff --git a/frontend/src/views/preference/Preference.vue b/frontend/src/views/preference/Preference.vue index 84527174b..66db43106 100644 --- a/frontend/src/views/preference/Preference.vue +++ b/frontend/src/views/preference/Preference.vue @@ -13,7 +13,6 @@ const data = reactive({ theme: settingsStore.theme }) - function save() { settingsStore.set_theme(data.theme) settingsStore.set_preference_theme(data.theme) diff --git a/frontend/version.json b/frontend/version.json index 7421b2306..75a1ec37d 100644 --- a/frontend/version.json +++ b/frontend/version.json @@ -1 +1 @@ -{"version":"1.7.0","build_id":61,"total_build":131} \ No newline at end of file +{"version":"1.7.0","build_id":62,"total_build":132} \ No newline at end of file diff --git a/server/pkg/cert/cert.go b/server/pkg/cert/cert.go index 710c5b991..8dc260c20 100644 --- a/server/pkg/cert/cert.go +++ b/server/pkg/cert/cert.go @@ -63,6 +63,10 @@ func IssueCert(domain []string, logChan chan string, errChan chan error) { config.CADirURL = "https://acme-staging-v02.api.letsencrypt.org/directory" } + if settings.ServerSettings.CADir != "" { + config.CADirURL = settings.ServerSettings.CADir + } + config.Certificate.KeyType = certcrypto.RSA2048 logChan <- "Creating client facilitates communication with the CA server" diff --git a/server/settings/settings.go b/server/settings/settings.go index cc182b02c..aaa243483 100644 --- a/server/settings/settings.go +++ b/server/settings/settings.go @@ -24,6 +24,7 @@ type Server struct { Email string Database string StartCmd string + CADir string Demo bool PageSize int } @@ -41,6 +42,7 @@ var ServerSettings = &Server{ StartCmd: "login", Demo: false, PageSize: 10, + CADir: "", } var NginxLogSettings = &NginxLog{ From 6bcb57544248e54a12c4babce771ff62b30f86ec Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Mon, 2 Jan 2023 14:14:24 +0800 Subject: [PATCH 07/22] feat: support for include location in server {} block #48 --- .../ngx_conf/directive/DirectiveEditor.vue | 84 +----------- .../directive/DirectiveEditorItem.vue | 121 ++++++++++++++++++ server/router/routers.go | 4 +- 3 files changed, 129 insertions(+), 80 deletions(-) create mode 100644 frontend/src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue diff --git a/frontend/src/views/domain/ngx_conf/directive/DirectiveEditor.vue b/frontend/src/views/domain/ngx_conf/directive/DirectiveEditor.vue index 0ed77bc89..d5c74dd8f 100644 --- a/frontend/src/views/domain/ngx_conf/directive/DirectiveEditor.vue +++ b/frontend/src/views/domain/ngx_conf/directive/DirectiveEditor.vue @@ -1,11 +1,9 @@ + + + + diff --git a/server/router/routers.go b/server/router/routers.go index 7be562112..54fec7cb1 100644 --- a/server/router/routers.go +++ b/server/router/routers.go @@ -74,9 +74,9 @@ func InitRouter() *gin.Engine { g.DELETE("domain/:name", api.DeleteDomain) g.GET("configs", api.GetConfigs) - g.GET("config/:name", api.GetConfig) + g.GET("config/*name", api.GetConfig) g.POST("config", api.AddConfig) - g.POST("config/:name", api.EditConfig) + g.POST("config/*name", api.EditConfig) //g.GET("backups", api.GetFileBackupList) //g.GET("backup/:id", api.GetFileBackup) From 65b192c8beab8dc74388b44e142023dd97fedfd1 Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Mon, 2 Jan 2023 18:38:40 +0800 Subject: [PATCH 08/22] feat: manage config support dir --- frontend/src/routes/index.ts | 12 +- frontend/src/views/config/Config.vue | 67 +++-- frontend/src/views/config/ConfigEdit.vue | 12 +- frontend/src/views/config/config.tsx | 41 +++ server/api/config.go | 303 +++++++++++------------ 5 files changed, 252 insertions(+), 183 deletions(-) create mode 100644 frontend/src/views/config/config.tsx diff --git a/frontend/src/routes/index.ts b/frontend/src/routes/index.ts index 68cce2cd6..2c843213f 100644 --- a/frontend/src/routes/index.ts +++ b/frontend/src/routes/index.ts @@ -74,7 +74,17 @@ export const routes = [ } }, { - path: 'config/:name', + path: 'config/:dir*', + name: () => $gettext('Manage Configs'), + component: () => import('@/views/config/Config.vue'), + meta: { + icon: FileOutlined, + hideChildren: true, + hiddenInSidebar: true + } + }, + { + path: 'config/:name+/edit', name: () => $gettext('Edit Configuration'), component: () => import('@/views/config/ConfigEdit.vue'), meta: { diff --git a/frontend/src/views/config/Config.vue b/frontend/src/views/config/Config.vue index ebe02dcf2..6f09d4ae7 100644 --- a/frontend/src/views/config/Config.vue +++ b/frontend/src/views/config/Config.vue @@ -2,43 +2,66 @@ import StdTable from '@/components/StdDataDisplay/StdTable.vue' import gettext from '@/gettext' import config from '@/api/config' -import {datetime} from '@/components/StdDataDisplay/StdTableTransformer' +import {customRender, datetime} from '@/components/StdDataDisplay/StdTableTransformer' +import {computed, h, nextTick, ref, watch} from 'vue' const {$gettext} = gettext const api = config -const columns = [{ - title: () => $gettext('Name'), - dataIndex: 'name', - sorter: true, - pithy: true -}, { - title: () => $gettext('Updated at'), - dataIndex: 'modify', - customRender: datetime, - datetime: true, - sorter: true, - pithy: true -}, { - title: () => $gettext('Action'), - dataIndex: 'action' -}] +import configColumns from '@/views/config/config' +import {useRoute} from 'vue-router' +import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue' +import router from '@/routes' + +const table = ref(null) +const route = useRoute() + +const basePath = computed(() => { + let dir = route?.params?.dir ? (route?.params?.dir as string[])?.join('/') : '' + if (dir) dir += '/' + return dir +}) + +const get_params = computed(() => { + return { + dir: basePath.value + } +}) + +const update = ref(1) + +watch(get_params, () => { + update.value++ +}) + diff --git a/frontend/src/views/config/ConfigEdit.vue b/frontend/src/views/config/ConfigEdit.vue index c3746edfc..18c4dd967 100644 --- a/frontend/src/views/config/ConfigEdit.vue +++ b/frontend/src/views/config/ConfigEdit.vue @@ -2,7 +2,7 @@ import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue' import gettext from '@/gettext' import {useRoute} from 'vue-router' -import {ref} from 'vue' +import {computed, ref} from 'vue' import config from '@/api/config' import {message} from 'ant-design-vue' import CodeEditor from '@/components/CodeEditor/CodeEditor.vue' @@ -10,7 +10,13 @@ import CodeEditor from '@/components/CodeEditor/CodeEditor.vue' const {$gettext, interpolate} = gettext const route = useRoute() -const name = ref(route.params.name) +const name = computed(() => { + const n = route.params.name + if (typeof n === 'string') { + return n + } + return n?.join('/') +}) const configText = ref('') @@ -46,7 +52,7 @@ function save() { - Cancel + Back Save diff --git a/frontend/src/views/config/config.tsx b/frontend/src/views/config/config.tsx new file mode 100644 index 000000000..662a77e79 --- /dev/null +++ b/frontend/src/views/config/config.tsx @@ -0,0 +1,41 @@ +import {customRender, datetime} from '@/components/StdDataDisplay/StdTableTransformer' +import gettext from '@/gettext' + +const {$gettext} = gettext + +import {Badge} from 'ant-design-vue' +import {h} from 'vue' + +const configColumns = [{ + title: () => $gettext('Name'), + dataIndex: 'name', + sorter: true, + pithy: true +}, { + title: () => $gettext('Type'), + dataIndex: 'is_dir', + customRender: (args: customRender) => { + const template: any = [] + const {text, column} = args + if (text === true || text > 0) { + template.push($gettext('Dir')) + } else { + template.push($gettext('File')) + } + return h('div', template) + }, + sorter: true, + pithy: true +}, { + title: () => $gettext('Updated at'), + dataIndex: 'modify', + customRender: datetime, + datetime: true, + sorter: true, + pithy: true +}, { + title: () => $gettext('Action'), + dataIndex: 'action' +}] + +export default configColumns diff --git a/server/api/config.go b/server/api/config.go index cd2e395aa..ebc24a92c 100644 --- a/server/api/config.go +++ b/server/api/config.go @@ -1,184 +1,173 @@ package api import ( - "github.com/0xJacky/Nginx-UI/server/pkg/config_list" - "github.com/0xJacky/Nginx-UI/server/pkg/nginx" - "github.com/gin-gonic/gin" - "log" - "net/http" - "os" - "path/filepath" - "strings" + "github.com/0xJacky/Nginx-UI/server/pkg/config_list" + "github.com/0xJacky/Nginx-UI/server/pkg/nginx" + "github.com/gin-gonic/gin" + "log" + "net/http" + "os" + "path/filepath" + "strings" ) func GetConfigs(c *gin.Context) { - orderBy := c.Query("order_by") - sort := c.DefaultQuery("sort", "desc") - - mySort := map[string]string{ - "name": "string", - "modify": "time", - } - - configFiles, err := os.ReadDir(nginx.GetNginxConfPath("/")) - - if err != nil { - ErrHandler(c, err) - return - } - - var configs []gin.H - - for i := range configFiles { - file := configFiles[i] - fileInfo, _ := file.Info() - - switch mode := fileInfo.Mode(); { - case mode.IsRegular(): // regular file, not a hidden file - if "." == file.Name()[0:1] { - continue - } - case mode&os.ModeSymlink != 0: // is a symbol - var targetPath string - targetPath, err = os.Readlink(nginx.GetNginxConfPath(file.Name())) - if err != nil { - log.Println("GetConfigs Read Symlink Error", targetPath, err) - continue - } - - var targetInfo os.FileInfo - targetInfo, err = os.Stat(targetPath) - if err != nil { - log.Println("GetConfigs Stat Error", targetPath, err) - continue - } - // but target file is not a dir - if targetInfo.IsDir() { - continue - } - default: - continue - } - - configs = append(configs, gin.H{ - "name": file.Name(), - "size": fileInfo.Size(), - "modify": fileInfo.ModTime(), - }) - } - - configs = config_list.Sort(orderBy, sort, mySort[orderBy], configs) - - c.JSON(http.StatusOK, gin.H{ - "data": configs, - }) + orderBy := c.Query("order_by") + sort := c.DefaultQuery("sort", "desc") + dir := c.DefaultQuery("dir", "/") + + mySort := map[string]string{ + "name": "string", + "modify": "time", + "is_dir": "bool", + } + + configFiles, err := os.ReadDir(nginx.GetNginxConfPath(dir)) + + if err != nil { + ErrHandler(c, err) + return + } + + var configs []gin.H + + for i := range configFiles { + file := configFiles[i] + fileInfo, _ := file.Info() + + switch mode := fileInfo.Mode(); { + case mode.IsRegular(): // regular file, not a hidden file + if "." == file.Name()[0:1] { + continue + } + case mode&os.ModeSymlink != 0: // is a symbol + var targetPath string + targetPath, err = os.Readlink(nginx.GetNginxConfPath(file.Name())) + if err != nil { + log.Println("GetConfigs Read Symlink Error", targetPath, err) + continue + } + } + + configs = append(configs, gin.H{ + "name": file.Name(), + "size": fileInfo.Size(), + "modify": fileInfo.ModTime(), + "is_dir": file.IsDir(), + }) + } + + configs = config_list.Sort(orderBy, sort, mySort[orderBy], configs) + + c.JSON(http.StatusOK, gin.H{ + "data": configs, + }) } func GetConfig(c *gin.Context) { - name := c.Param("name") - path := filepath.Join(nginx.GetNginxConfPath("/"), name) + name := c.Param("name") + path := filepath.Join(nginx.GetNginxConfPath("/"), name) - content, err := os.ReadFile(path) + content, err := os.ReadFile(path) - if err != nil { - ErrHandler(c, err) - return - } + if err != nil { + ErrHandler(c, err) + return + } - c.JSON(http.StatusOK, gin.H{ - "config": string(content), - }) + c.JSON(http.StatusOK, gin.H{ + "config": string(content), + }) } type AddConfigJson struct { - Name string `json:"name" binding:"required"` - Content string `json:"content" binding:"required"` + Name string `json:"name" binding:"required"` + Content string `json:"content" binding:"required"` } func AddConfig(c *gin.Context) { - var request AddConfigJson - err := c.BindJSON(&request) - if err != nil { - ErrHandler(c, err) - return - } - - name := request.Name - content := request.Content - - path := filepath.Join(nginx.GetNginxConfPath("/"), name) - - log.Println(path) - if _, err = os.Stat(path); err == nil { - c.JSON(http.StatusNotAcceptable, gin.H{ - "message": "config exist", - }) - return - } - - if content != "" { - err = os.WriteFile(path, []byte(content), 0644) - if err != nil { - ErrHandler(c, err) - return - } - } - - output := nginx.ReloadNginx() - - if output != "" && strings.Contains(output, "error") { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": output, - }) - return - } - - c.JSON(http.StatusOK, gin.H{ - "name": name, - "content": content, - }) + var request AddConfigJson + err := c.BindJSON(&request) + if err != nil { + ErrHandler(c, err) + return + } + + name := request.Name + content := request.Content + + path := filepath.Join(nginx.GetNginxConfPath("/"), name) + + if _, err = os.Stat(path); err == nil { + c.JSON(http.StatusNotAcceptable, gin.H{ + "message": "config exist", + }) + return + } + + if content != "" { + err = os.WriteFile(path, []byte(content), 0644) + if err != nil { + ErrHandler(c, err) + return + } + } + + output := nginx.ReloadNginx() + + if output != "" && strings.Contains(output, "error") { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": output, + }) + return + } + + c.JSON(http.StatusOK, gin.H{ + "name": name, + "content": content, + }) } type EditConfigJson struct { - Content string `json:"content" binding:"required"` + Content string `json:"content" binding:"required"` } func EditConfig(c *gin.Context) { - name := c.Param("name") - var request EditConfigJson - err := c.BindJSON(&request) - if err != nil { - ErrHandler(c, err) - return - } - path := filepath.Join(nginx.GetNginxConfPath("/"), name) - content := request.Content - - origContent, err := os.ReadFile(path) - if err != nil { - ErrHandler(c, err) - return - } - - if content != "" && content != string(origContent) { - // model.CreateBackup(path) - err = os.WriteFile(path, []byte(content), 0644) - if err != nil { - ErrHandler(c, err) - return - } - } - - output := nginx.ReloadNginx() - - if output != "" && strings.Contains(output, "error") { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": output, - }) - return - } - - GetConfig(c) + name := c.Param("name") + var request EditConfigJson + err := c.BindJSON(&request) + if err != nil { + ErrHandler(c, err) + return + } + path := filepath.Join(nginx.GetNginxConfPath("/"), name) + content := request.Content + + origContent, err := os.ReadFile(path) + if err != nil { + ErrHandler(c, err) + return + } + + if content != "" && content != string(origContent) { + // model.CreateBackup(path) + err = os.WriteFile(path, []byte(content), 0644) + if err != nil { + ErrHandler(c, err) + return + } + } + + output := nginx.ReloadNginx() + + if output != "" && strings.Contains(output, "error") { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": output, + }) + return + } + + GetConfig(c) } From 0f58c86613639119a11f49f243f8990e8ff0c798 Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Mon, 2 Jan 2023 21:08:02 +0800 Subject: [PATCH 09/22] feat: Online modify settings #32 --- frontend/components.d.ts | 1 + frontend/src/api/settings.ts | 12 ++++ .../directive/DirectiveEditorItem.vue | 9 ++- frontend/src/views/preference/Preference.vue | 58 ++++++++++++++++--- server/api/settings.go | 38 ++++++++++++ server/router/routers.go | 12 ++-- server/settings/settings.go | 25 ++++---- template/template.go | 6 ++ 8 files changed, 130 insertions(+), 31 deletions(-) create mode 100644 frontend/src/api/settings.ts create mode 100644 server/api/settings.go create mode 100644 template/template.go diff --git a/frontend/components.d.ts b/frontend/components.d.ts index da24afcaa..d7ff438d3 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -21,6 +21,7 @@ declare module '@vue/runtime-core' { AFormItem: typeof import('ant-design-vue/es')['FormItem'] AInput: typeof import('ant-design-vue/es')['Input'] AInputGroup: typeof import('ant-design-vue/es')['InputGroup'] + AInputNumber: typeof import('ant-design-vue/es')['InputNumber'] AInputPassword: typeof import('ant-design-vue/es')['InputPassword'] ALayout: typeof import('ant-design-vue/es')['Layout'] ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent'] diff --git a/frontend/src/api/settings.ts b/frontend/src/api/settings.ts new file mode 100644 index 000000000..30e03c31d --- /dev/null +++ b/frontend/src/api/settings.ts @@ -0,0 +1,12 @@ +import http from '@/lib/http' + +const settings = { + get() { + return http.get('/settings') + }, + save(data: any) { + return http.post('/settings', data) + } +} + +export default settings diff --git a/frontend/src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue b/frontend/src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue index e32176b27..a251ea70f 100644 --- a/frontend/src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue +++ b/frontend/src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue @@ -40,7 +40,7 @@ function save() { diff --git a/frontend/src/views/preference/Preference.vue b/frontend/src/views/preference/Preference.vue index 66db43106..8cd7e4f4f 100644 --- a/frontend/src/views/preference/Preference.vue +++ b/frontend/src/views/preference/Preference.vue @@ -1,22 +1,45 @@ @@ -24,8 +47,23 @@ function save() {
+ +

{{ data.server.http_port }}

+
+ +

{{ data.server.run_mode }}

+
+ +

{{ data.server.jwt_secret }}

+
+ +

{{ data.server.start_cmd }}

+
+ + + - + {{ $gettext('Auto') }} @@ -37,6 +75,12 @@ function save() { + + + + + +
diff --git a/server/api/settings.go b/server/api/settings.go new file mode 100644 index 000000000..3403ff28a --- /dev/null +++ b/server/api/settings.go @@ -0,0 +1,38 @@ +package api + +import ( + "github.com/0xJacky/Nginx-UI/server/settings" + "github.com/gin-gonic/gin" + "net/http" +) + +func GetSettings(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "server": settings.ServerSettings, + "nginx_log": settings.NginxLogSettings, + }) +} + +func SaveSettings(c *gin.Context) { + var json struct { + Server settings.Server `json:"server"` + NginxLog settings.NginxLog `json:"nginx_log"` + } + + if !BindAndValid(c, &json) { + return + } + + settings.Conf.Section("server").Key("Email").SetValue(json.Server.Email) + settings.Conf.Section("server").Key("HTTPChallengePort").SetValue(json.Server.HTTPChallengePort) + settings.Conf.Section("nginx_log").Key("AccessLogPath").SetValue(json.NginxLog.AccessLogPath) + settings.Conf.Section("nginx_log").Key("ErrorLogPath").SetValue(json.NginxLog.ErrorLogPath) + + err := settings.Save() + if err != nil { + ErrHandler(c, err) + return + } + + GetSettings(c) +} diff --git a/server/router/routers.go b/server/router/routers.go index 54fec7cb1..b60173505 100644 --- a/server/router/routers.go +++ b/server/router/routers.go @@ -3,7 +3,6 @@ package router import ( "bufio" "github.com/0xJacky/Nginx-UI/server/api" - "github.com/0xJacky/Nginx-UI/server/settings" "github.com/gin-contrib/static" "github.com/gin-gonic/gin" "net/http" @@ -34,13 +33,6 @@ func InitRouter() *gin.Engine { root := r.Group("/api") { - - root.GET("settings", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{ - "demo": settings.ServerSettings.Demo, - }) - }) - root.GET("install", api.InstallLockCheck) root.POST("install", api.InstallNginxUI) @@ -96,6 +88,10 @@ func InitRouter() *gin.Engine { // Nginx log g.GET("nginx_log", api.NginxLog) g.POST("nginx_log", api.GetNginxLogPage) + + // Settings + g.GET("settings", api.GetSettings) + g.POST("settings", api.SaveSettings) } } diff --git a/server/settings/settings.go b/server/settings/settings.go index aaa243483..2b4c53596 100644 --- a/server/settings/settings.go +++ b/server/settings/settings.go @@ -16,22 +16,21 @@ var ( ) type Server struct { - HttpPort string - RunMode string - WebSocketToken string - JwtSecret string - HTTPChallengePort string - Email string - Database string - StartCmd string - CADir string - Demo bool - PageSize int + HttpPort string `json:"http_port"` + RunMode string `json:"run_mode"` + JwtSecret string `json:"jwt_secret"` + HTTPChallengePort string `json:"http_challenge_port"` + Email string `json:"email"` + Database string `json:"database"` + StartCmd string `json:"start_cmd"` + CADir string `json:"ca_dir"` + Demo bool `json:"demo"` + PageSize int `json:"page_size"` } type NginxLog struct { - AccessLogPath string - ErrorLogPath string + AccessLogPath string `json:"access_log_path"` + ErrorLogPath string `json:"error_log_path"` } var ServerSettings = &Server{ diff --git a/template/template.go b/template/template.go new file mode 100644 index 000000000..1c424a742 --- /dev/null +++ b/template/template.go @@ -0,0 +1,6 @@ +package template + +import "embed" + +//go:embed * +var DistFS embed.FS From 4a3e32a921970666bff5d6b26b9edb0a6eaf930f Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Mon, 2 Jan 2023 21:11:02 +0800 Subject: [PATCH 10/22] chore: update translate --- frontend/src/language/en/app.po | 111 ++++++++++++++-------- frontend/src/language/messages.pot | 105 ++++++++++++++------- frontend/src/language/translations.json | 2 +- frontend/src/language/zh_CN/app.mo | Bin 9553 -> 9936 bytes frontend/src/language/zh_CN/app.po | 113 +++++++++++++++-------- frontend/src/language/zh_TW/app.po | 118 ++++++++++++++++-------- 6 files changed, 298 insertions(+), 151 deletions(-) diff --git a/frontend/src/language/en/app.po b/frontend/src/language/en/app.po index be27c8d57..303d0066a 100644 --- a/frontend/src/language/en/app.po +++ b/frontend/src/language/en/app.po @@ -9,16 +9,15 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: src/routes/index.ts:125 +#: src/routes/index.ts:135 msgid "About" msgstr "About" -#: src/routes/index.ts:100 src/views/domain/ngx_conf/LogEntry.vue:64 +#: src/routes/index.ts:110 src/views/domain/ngx_conf/LogEntry.vue:64 msgid "Access Logs" msgstr "" -#: src/views/config/Config.vue:24 src/views/domain/DomainList.vue:47 -#: src/views/user/User.vue:43 +#: src/views/domain/DomainList.vue:47 src/views/user/User.vue:43 msgid "Action" msgstr "Action" @@ -54,7 +53,7 @@ msgstr "Advance Mode" msgid "Are you sure you want to delete?" msgstr "Are you sure you want to remove this directive?" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:27 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:16 msgid "Are you sure you want to remove this directive?" msgstr "Are you sure you want to remove this directive?" @@ -63,7 +62,8 @@ msgstr "Are you sure you want to remove this directive?" msgid "Are you sure you want to remove this location?" msgstr "Are you sure you want to remove this directive?" -#: src/views/preference/Preference.vue:7 src/views/preference/Preference.vue:8 +#: src/views/preference/Preference.vue:22 +#: src/views/preference/Preference.vue:23 msgid "Auto" msgstr "" @@ -79,7 +79,10 @@ msgstr "Auto-renewal disabled for %{name}" msgid "Auto-renewal enabled for %{name}" msgstr "Auto-renewal enabled for %{name}" -#: src/views/domain/DomainEdit.vue:187 src/views/nginx_log/NginxLog.vue:173 +#: src/views/config/Config.vue:14 src/views/config/Config.vue:15 +#: src/views/config/Config.vue:25 src/views/config/Config.vue:5 +#: src/views/config/ConfigEdit.vue:55 src/views/domain/DomainEdit.vue:187 +#: src/views/nginx_log/NginxLog.vue:173 msgid "Back" msgstr "Back" @@ -112,7 +115,6 @@ msgstr "Build with" #: src/components/StdDataDisplay/StdCurd.vue:27 #: src/components/StdDataEntry/components/StdSelector.vue:11 #: src/components/StdDataEntry/compontents/StdSelector.vue:11 -#: src/views/config/ConfigEdit.vue:49 msgid "Cancel" msgstr "Cancel" @@ -128,7 +130,7 @@ msgstr "Certificate is valid" msgid "Certificate Status" msgstr "Certificate Status" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:41 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:30 #: src/views/domain/ngx_conf/LocationEditor.vue:31 #: src/views/domain/ngx_conf/LocationEditor.vue:47 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 @@ -147,6 +149,7 @@ msgstr "Configurations" msgid "Configure SSL" msgstr "Configure SSL" +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:33 #: src/views/domain/ngx_conf/LocationEditor.vue:37 #: src/views/domain/ngx_conf/LocationEditor.vue:53 msgid "Content" @@ -172,8 +175,8 @@ msgstr "Created at" msgid "Creating client facilitates communication with the CA server" msgstr "" -#: src/views/preference/Preference.vue:13 -#: src/views/preference/Preference.vue:14 +#: src/views/preference/Preference.vue:28 +#: src/views/preference/Preference.vue:29 msgid "Dark" msgstr "" @@ -238,7 +241,7 @@ msgstr "Domain Config Created Successfully" msgid "Edit %{n}" msgstr "Edit %{n}" -#: src/routes/index.ts:78 src/views/config/ConfigEdit.vue:2 +#: src/routes/index.ts:88 src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "Edit Configuration" @@ -278,7 +281,7 @@ msgstr "Enabled successfully" msgid "Encrypt website with Let's Encrypt" msgstr "Encrypt website with Let's Encrypt" -#: src/routes/index.ts:104 src/views/domain/ngx_conf/LogEntry.vue:68 +#: src/routes/index.ts:114 src/views/domain/ngx_conf/LogEntry.vue:68 msgid "Error Logs" msgstr "" @@ -334,7 +337,15 @@ msgstr "Getting the certificate, please wait..." msgid "Home" msgstr "Home" -#: src/routes/index.ts:135 src/views/other/Install.vue:128 +#: src/views/preference/Preference.vue:17 +msgid "HTTP Challenge Port" +msgstr "" + +#: src/views/preference/Preference.vue:5 +msgid "HTTP Port" +msgstr "" + +#: src/routes/index.ts:145 src/views/other/Install.vue:128 msgid "Install" msgstr "Install" @@ -352,12 +363,16 @@ msgstr "Intermediate Certification Authorities: %{issuer}" msgid "Issued certificate successfully" msgstr "Enabled successfully" +#: src/views/preference/Preference.vue:11 +msgid "Jwt Secret" +msgstr "" + #: src/views/user/User.vue:26 msgid "Leave blank for no change" msgstr "Leave blank for no change" -#: src/views/preference/Preference.vue:10 -#: src/views/preference/Preference.vue:11 +#: src/views/preference/Preference.vue:25 +#: src/views/preference/Preference.vue:26 msgid "Light" msgstr "" @@ -375,7 +390,7 @@ msgstr "Location" msgid "Locations" msgstr "Locations" -#: src/routes/index.ts:141 src/views/other/Login.vue:103 +#: src/routes/index.ts:151 src/views/other/Login.vue:103 msgid "Login" msgstr "Login" @@ -395,7 +410,7 @@ msgstr "" "Make sure you have configured a reverse proxy for .well-known directory to " "HTTPChallengePort (default: 9180) before getting the certificate." -#: src/routes/index.ts:69 +#: src/routes/index.ts:69 src/routes/index.ts:78 msgid "Manage Configs" msgstr "Manage Configs" @@ -429,8 +444,7 @@ msgstr "Modify Config" msgid "Modify Config" msgstr "Modify Config" -#: src/views/config/Config.vue:12 src/views/domain/DomainEdit.vue:36 -#: src/views/domain/DomainList.vue:15 +#: src/views/domain/DomainEdit.vue:36 src/views/domain/DomainList.vue:15 msgid "Name" msgstr "Name" @@ -454,18 +468,26 @@ msgstr "Network Total Send" msgid "Next" msgstr "Next" -#: src/routes/index.ts:94 src/views/nginx_log/NginxLog.vue:2 +#: src/views/preference/Preference.vue:33 +msgid "Nginx Access Log Path" +msgstr "" + +#: src/views/preference/Preference.vue:36 +msgid "Nginx Error Log Path" +msgstr "" + +#: src/routes/index.ts:104 src/views/nginx_log/NginxLog.vue:2 msgid "Nginx Log" msgstr "" #: src/components/StdDataDisplay/StdTable.vue:52 #: src/views/domain/DomainList.vue:24 -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:18 #: src/views/domain/ngx_conf/LocationEditor.vue:21 msgid "No" msgstr "No" -#: src/routes/index.ts:147 src/routes/index.ts:149 +#: src/routes/index.ts:157 src/routes/index.ts:159 msgid "Not Found" msgstr "Not Found" @@ -527,7 +549,7 @@ msgstr "Please input your password!" msgid "Please input your username!" msgstr "Please input your username!" -#: src/routes/index.ts:117 src/views/preference/Preference.vue:2 +#: src/routes/index.ts:127 src/views/preference/Preference.vue:2 msgid "Preference" msgstr "" @@ -570,9 +592,18 @@ msgstr "" msgid "Reset" msgstr "" -#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:190 -#: src/views/preference/Preference.vue:22 -#: src/views/preference/Preference.vue:23 +#: src/views/preference/Preference.vue:8 +#, fuzzy +msgid "Run Mode" +msgstr "Advance Mode" + +#: src/views/config/ConfigEdit.vue:58 src/views/domain/DomainEdit.vue:190 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:30 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:31 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:36 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37 +#: src/views/preference/Preference.vue:43 +#: src/views/preference/Preference.vue:44 msgid "Save" msgstr "Save" @@ -582,11 +613,13 @@ msgstr "Save" msgid "Save Directive" msgstr "Save Directive" -#: src/views/config/ConfigEdit.vue:36 src/views/domain/DomainAdd.vue:54 +#: src/views/config/ConfigEdit.vue:42 src/views/domain/DomainAdd.vue:54 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37 msgid "Save error %{msg}" msgstr "Save error %{msg}" #: src/components/StdDataDisplay/StdBatchEdit.vue:40 +#: src/views/preference/Preference.vue:39 #, fuzzy msgid "Save successfully" msgstr "Saved successfully" @@ -596,8 +629,9 @@ msgstr "Saved successfully" msgid "Save Successfully" msgstr "Saved successfully" -#: src/views/config/ConfigEdit.vue:34 src/views/domain/DomainAdd.vue:43 +#: src/views/config/ConfigEdit.vue:40 src/views/domain/DomainAdd.vue:43 #: src/views/domain/DomainEdit.vue:97 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:35 msgid "Saved successfully" msgstr "Saved successfully" @@ -614,10 +648,10 @@ msgstr "Send" #: src/components/StdDataDisplay/StdTable.vue:168 #: src/components/StdDataDisplay/StdTable.vue:343 #: src/components/StdDataDisplay/StdTable.vue:463 -#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:100 +#: src/views/config/ConfigEdit.vue:28 src/views/domain/DomainEdit.vue:100 #: src/views/domain/DomainEdit.vue:62 src/views/domain/DomainEdit.vue:74 #: src/views/domain/DomainEdit.vue:83 src/views/domain/DomainList.vue:83 -#: src/views/other/Install.vue:71 +#: src/views/other/Install.vue:71 src/views/preference/Preference.vue:41 msgid "Server error" msgstr "Server error" @@ -638,7 +672,7 @@ msgstr "server_name parameter is required" msgid "Single Directive" msgstr "Single Directive" -#: src/routes/index.ts:108 +#: src/routes/index.ts:118 #, fuzzy msgid "Site Logs" msgstr "Sites List" @@ -668,10 +702,14 @@ msgstr "Swap" msgid "Table" msgstr "Enabled" -#: src/routes/index.ts:86 src/views/pty/Terminal.vue:2 +#: src/routes/index.ts:96 src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "Terminal" +#: src/views/preference/Preference.vue:14 +msgid "Terminal Start Command" +msgstr "" + #: src/views/domain/cert/IssueCert.vue:205 msgid "" "The certificate for the domain will be checked every hour, and will be " @@ -688,12 +726,11 @@ msgstr "The filename cannot contain the following characters: %{c}" msgid "The username or password is incorrect" msgstr "" -#: src/views/preference/Preference.vue:5 +#: src/views/preference/Preference.vue:20 msgid "Theme" msgstr "" -#: src/views/config/Config.vue:17 src/views/domain/DomainList.vue:41 -#: src/views/user/User.vue:37 +#: src/views/domain/DomainList.vue:41 src/views/user/User.vue:37 msgid "Updated at" msgstr "Updated at" @@ -735,7 +772,7 @@ msgstr "" msgid "Writing certificate to disk" msgstr "" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:28 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:17 #: src/views/domain/ngx_conf/LocationEditor.vue:20 msgid "Yes" msgstr "Yes" diff --git a/frontend/src/language/messages.pot b/frontend/src/language/messages.pot index d8dbb625e..18fa02338 100644 --- a/frontend/src/language/messages.pot +++ b/frontend/src/language/messages.pot @@ -2,16 +2,15 @@ msgid "" msgstr "" "Content-Type: text/plain; charset=UTF-8\n" -#: src/routes/index.ts:125 +#: src/routes/index.ts:135 msgid "About" msgstr "" -#: src/routes/index.ts:100 +#: src/routes/index.ts:110 #: src/views/domain/ngx_conf/LogEntry.vue:64 msgid "Access Logs" msgstr "" -#: src/views/config/Config.vue:24 #: src/views/domain/DomainList.vue:47 #: src/views/user/User.vue:43 msgid "Action" @@ -50,7 +49,7 @@ msgstr "" msgid "Are you sure you want to delete?" msgstr "" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:27 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:16 msgid "Are you sure you want to remove this directive?" msgstr "" @@ -58,8 +57,8 @@ msgstr "" msgid "Are you sure you want to remove this location?" msgstr "" -#: src/views/preference/Preference.vue:7 -#: src/views/preference/Preference.vue:8 +#: src/views/preference/Preference.vue:22 +#: src/views/preference/Preference.vue:23 msgid "Auto" msgstr "" @@ -75,6 +74,11 @@ msgstr "" msgid "Auto-renewal enabled for %{name}" msgstr "" +#: src/views/config/Config.vue:14 +#: src/views/config/Config.vue:15 +#: src/views/config/Config.vue:25 +#: src/views/config/Config.vue:5 +#: src/views/config/ConfigEdit.vue:55 #: src/views/domain/DomainEdit.vue:187 #: src/views/nginx_log/NginxLog.vue:173 msgid "Back" @@ -108,7 +112,6 @@ msgstr "" #: src/components/StdDataDisplay/StdCurd.vue:27 #: src/components/StdDataEntry/components/StdSelector.vue:11 #: src/components/StdDataEntry/compontents/StdSelector.vue:11 -#: src/views/config/ConfigEdit.vue:49 msgid "Cancel" msgstr "" @@ -124,7 +127,7 @@ msgstr "" msgid "Certificate Status" msgstr "" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:41 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:30 #: src/views/domain/ngx_conf/LocationEditor.vue:31 #: src/views/domain/ngx_conf/LocationEditor.vue:47 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 @@ -143,6 +146,7 @@ msgstr "" msgid "Configure SSL" msgstr "" +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:33 #: src/views/domain/ngx_conf/LocationEditor.vue:37 #: src/views/domain/ngx_conf/LocationEditor.vue:53 msgid "Content" @@ -168,8 +172,8 @@ msgstr "" msgid "Creating client facilitates communication with the CA server" msgstr "" -#: src/views/preference/Preference.vue:13 -#: src/views/preference/Preference.vue:14 +#: src/views/preference/Preference.vue:28 +#: src/views/preference/Preference.vue:29 msgid "Dark" msgstr "" @@ -240,7 +244,7 @@ msgstr "" msgid "Edit %{n}" msgstr "" -#: src/routes/index.ts:78 +#: src/routes/index.ts:88 #: src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "" @@ -286,7 +290,7 @@ msgstr "" msgid "Encrypt website with Let's Encrypt" msgstr "" -#: src/routes/index.ts:104 +#: src/routes/index.ts:114 #: src/views/domain/ngx_conf/LogEntry.vue:68 msgid "Error Logs" msgstr "" @@ -347,7 +351,15 @@ msgstr "" msgid "Home" msgstr "" -#: src/routes/index.ts:135 +#: src/views/preference/Preference.vue:17 +msgid "HTTP Challenge Port" +msgstr "" + +#: src/views/preference/Preference.vue:5 +msgid "HTTP Port" +msgstr "" + +#: src/routes/index.ts:145 #: src/views/other/Install.vue:128 msgid "Install" msgstr "" @@ -364,12 +376,16 @@ msgstr "" msgid "Issued certificate successfully" msgstr "" +#: src/views/preference/Preference.vue:11 +msgid "Jwt Secret" +msgstr "" + #: src/views/user/User.vue:26 msgid "Leave blank for no change" msgstr "" -#: src/views/preference/Preference.vue:10 -#: src/views/preference/Preference.vue:11 +#: src/views/preference/Preference.vue:25 +#: src/views/preference/Preference.vue:26 msgid "Light" msgstr "" @@ -387,7 +403,7 @@ msgstr "" msgid "Locations" msgstr "" -#: src/routes/index.ts:141 +#: src/routes/index.ts:151 #: src/views/other/Login.vue:103 msgid "Login" msgstr "" @@ -405,6 +421,7 @@ msgid "Make sure you have configured a reverse proxy for .well-known directory t msgstr "" #: src/routes/index.ts:69 +#: src/routes/index.ts:78 msgid "Manage Configs" msgstr "" @@ -439,7 +456,6 @@ msgstr "" msgid "Modify Config" msgstr "" -#: src/views/config/Config.vue:12 #: src/views/domain/DomainEdit.vue:36 #: src/views/domain/DomainList.vue:15 msgid "Name" @@ -465,20 +481,28 @@ msgstr "" msgid "Next" msgstr "" -#: src/routes/index.ts:94 +#: src/views/preference/Preference.vue:33 +msgid "Nginx Access Log Path" +msgstr "" + +#: src/views/preference/Preference.vue:36 +msgid "Nginx Error Log Path" +msgstr "" + +#: src/routes/index.ts:104 #: src/views/nginx_log/NginxLog.vue:2 msgid "Nginx Log" msgstr "" #: src/components/StdDataDisplay/StdTable.vue:52 #: src/views/domain/DomainList.vue:24 -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:18 #: src/views/domain/ngx_conf/LocationEditor.vue:21 msgid "No" msgstr "" -#: src/routes/index.ts:147 -#: src/routes/index.ts:149 +#: src/routes/index.ts:157 +#: src/routes/index.ts:159 msgid "Not Found" msgstr "" @@ -540,7 +564,7 @@ msgstr "" msgid "Please input your username!" msgstr "" -#: src/routes/index.ts:117 +#: src/routes/index.ts:127 #: src/views/preference/Preference.vue:2 msgid "Preference" msgstr "" @@ -584,10 +608,18 @@ msgstr "" msgid "Reset" msgstr "" -#: src/views/config/ConfigEdit.vue:52 +#: src/views/preference/Preference.vue:8 +msgid "Run Mode" +msgstr "" + +#: src/views/config/ConfigEdit.vue:58 #: src/views/domain/DomainEdit.vue:190 -#: src/views/preference/Preference.vue:22 -#: src/views/preference/Preference.vue:23 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:30 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:31 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:36 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37 +#: src/views/preference/Preference.vue:43 +#: src/views/preference/Preference.vue:44 msgid "Save" msgstr "" @@ -597,12 +629,14 @@ msgstr "" msgid "Save Directive" msgstr "" -#: src/views/config/ConfigEdit.vue:36 +#: src/views/config/ConfigEdit.vue:42 #: src/views/domain/DomainAdd.vue:54 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37 msgid "Save error %{msg}" msgstr "" #: src/components/StdDataDisplay/StdBatchEdit.vue:40 +#: src/views/preference/Preference.vue:39 msgid "Save successfully" msgstr "" @@ -610,9 +644,10 @@ msgstr "" msgid "Save Successfully" msgstr "" -#: src/views/config/ConfigEdit.vue:34 +#: src/views/config/ConfigEdit.vue:40 #: src/views/domain/DomainAdd.vue:43 #: src/views/domain/DomainEdit.vue:97 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:35 msgid "Saved successfully" msgstr "" @@ -630,13 +665,14 @@ msgstr "" #: src/components/StdDataDisplay/StdTable.vue:168 #: src/components/StdDataDisplay/StdTable.vue:343 #: src/components/StdDataDisplay/StdTable.vue:463 -#: src/views/config/ConfigEdit.vue:22 +#: src/views/config/ConfigEdit.vue:28 #: src/views/domain/DomainEdit.vue:100 #: src/views/domain/DomainEdit.vue:62 #: src/views/domain/DomainEdit.vue:74 #: src/views/domain/DomainEdit.vue:83 #: src/views/domain/DomainList.vue:83 #: src/views/other/Install.vue:71 +#: src/views/preference/Preference.vue:41 msgid "Server error" msgstr "" @@ -658,7 +694,7 @@ msgstr "" msgid "Single Directive" msgstr "" -#: src/routes/index.ts:108 +#: src/routes/index.ts:118 msgid "Site Logs" msgstr "" @@ -686,11 +722,15 @@ msgstr "" msgid "Table" msgstr "" -#: src/routes/index.ts:86 +#: src/routes/index.ts:96 #: src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "" +#: src/views/preference/Preference.vue:14 +msgid "Terminal Start Command" +msgstr "" + #: src/views/domain/cert/IssueCert.vue:205 msgid "The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued." msgstr "" @@ -703,11 +743,10 @@ msgstr "" msgid "The username or password is incorrect" msgstr "" -#: src/views/preference/Preference.vue:5 +#: src/views/preference/Preference.vue:20 msgid "Theme" msgstr "" -#: src/views/config/Config.vue:17 #: src/views/domain/DomainList.vue:41 #: src/views/user/User.vue:37 msgid "Updated at" @@ -753,7 +792,7 @@ msgstr "" msgid "Writing certificate to disk" msgstr "" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:28 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:17 #: src/views/domain/ngx_conf/LocationEditor.vue:20 msgid "Yes" msgstr "" diff --git a/frontend/src/language/translations.json b/frontend/src/language/translations.json index 9f70a0142..bd22dd781 100644 --- a/frontend/src/language/translations.json +++ b/frontend/src/language/translations.json @@ -1 +1 @@ -{"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Auto":"自動","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Comments":"註釋","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Development Mode":"開發模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Domain Config Created Successfully":"域名配置文件創建成功","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error Logs":"錯誤日志","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","Next":"下一步","Nginx Log":"Nginx 日誌","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:當前配置中的 server_name 必須為需要申請證書的域名。","Obtaining certificate":"正在獲取證書,請稍等...","OK":"確定","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reloading nginx":"重载 Nginx","Reset":"重設","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","Table":"表格","Terminal":"終端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Updated at":"修改時間","Updated successfully":"已成功更新","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","License":{"Project":"開源軟體授權條款"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"Note: The server_name in the current configuration must be the domain name you need to get the certificate.","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}},"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Auto":"自动","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Comments":"注释","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Development Mode":"开发模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Domain Config Created Successfully":"域名配置文件创建成功","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","Next":"下一步","Nginx Log":"Nginx 日志","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:当前配置中的 server_name 必须为需要申请证书的域名。","Obtaining certificate":"正在获取证书","OK":"确定","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reloading nginx":"正在重载 Nginx","Reset":"重置","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","Table":"列表","Terminal":"终端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Updated at":"修改时间","Updated successfully":"更新成功","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","License":{"Project":"开源许可"}}} \ No newline at end of file +{"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Auto":"自动","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Comments":"注释","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Development Mode":"开发模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Domain Config Created Successfully":"域名配置文件创建成功","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","HTTP Challenge Port":"HTTP Challenge 监听端口","HTTP Port":"HTTP 监听端口","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Jwt Secret":"Jwt 密钥","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","Next":"下一步","Nginx Access Log Path":"Nginx 访问日志路径","Nginx Error Log Path":"Nginx 错误日志路径","Nginx Log":"Nginx 日志","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:当前配置中的 server_name 必须为需要申请证书的域名。","Obtaining certificate":"正在获取证书","OK":"确定","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reloading nginx":"正在重载 Nginx","Reset":"重置","Run Mode":"运行模式","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","Table":"列表","Terminal":"终端","Terminal Start Command":"终端启动命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Updated at":"修改时间","Updated successfully":"更新成功","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","License":{"Project":"开源许可"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"Note: The server_name in the current configuration must be the domain name you need to get the certificate.","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}},"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Auto":"自動","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Comments":"註釋","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Development Mode":"開發模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Domain Config Created Successfully":"域名配置文件創建成功","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error Logs":"錯誤日志","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","Next":"下一步","Nginx Log":"Nginx 日誌","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:當前配置中的 server_name 必須為需要申請證書的域名。","Obtaining certificate":"正在獲取證書,請稍等...","OK":"確定","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reloading nginx":"重载 Nginx","Reset":"重設","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","Table":"表格","Terminal":"終端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Updated at":"修改時間","Updated successfully":"已成功更新","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","License":{"Project":"開源軟體授權條款"}}} \ No newline at end of file diff --git a/frontend/src/language/zh_CN/app.mo b/frontend/src/language/zh_CN/app.mo index 214f2996f36b0f09cc67fff5b0c9a236cd2641f1..9c51b4baac0849389bc12bf9d45895bbbca0fe78 100644 GIT binary patch delta 3945 zcmYk;c~F&A7{~Dgq9E=lkqdfLG0m+s%`G)aEnHGuQLJu?V6oT*6-~M=WI~H58d*x3 zpp*(Z!<(s6hr}=-1 ziP+*uRYW%;wYhWWaa%MWq`qyPqssNeRyY`2;Am`y6R;yr!q&I|qcGjd%h5x*00(0^ z4#HCy;hf(!lF^Of?VP&}+o1>VLK?VaY>D%*J$g}N^P%o5uyV1v1$EyJ)IcjS2KQkc z)?p_+gHiPFezykKkg>QZdTE1k7>Nm}`hlp9$KV*8jOwTmHNYb5gQcjB4V?H|L zX)FJZYTt;_^zR}&ICne7pq6eF#$qCB04dlLy{H=tQ8Rkg$~(=yr~w{C4df%#MCwt` zxrUl~BkFlEJjAaXhLO1y$D>A`V&z9sOST#la3g9Z4x!q8jvDZn=Jz;=@;TIm+Hx>- zHiq+|fhVC>Y&Hfb){*tsh`dzXg)6ZKR-p!V0=0DCq7LC7r~zC-bsWykdT=Y$^;l$8 zT~}n1ZUDZFV^Q~gfjToknDw1lf6e476%5+lK$Y9F{#v?N)QEebM%)+G?oQ;-C0aQJ z)h^TOpF|$zUPKLW8;0X7@R8QA@ZGHB&EYDVL!duCeRIsDYHA z2Cx;iwB@KJ-*48L-=J3PJnFvdsQdmwzEAuvf|I8Kv`2Lqk6N-ps2Pkvtw17bU`eQz zNk%;=12yn0R0p}pB;8sp!crWC@hnpU&PTO>8l(087n0FlZ9sKUfqKwB)W8m+4&^6y z{a4h0enTzkU#O+;+$FSi!>||Sk*F`UMHn8&R8jXmM`Jy=2wTvl^v;$&%{T~XKjqnI19) z33WCC$SS()s0VcD9_qNenSh%404q;NwVQ)_?qkTG%j82pW-oPT{nen13R!^~@d5KF z>Ve1Y`X$s%uUokhbq1n2Ai94DY757q+RZ_}t6ZwN9JPgosFm36C!>b@&G*eCsJ;CJ zHGq0#yIo69=rv0~-FJ^U7Bzs0sKb|x+M<=H2^FCRwi$KbyQnWX{{b>O?RBUnI)Q3% z8uh@l=0#jf`HGd7Gb&v#FpE+5m7!) zuPf<6bvP2$(Iiwy(@-;8gb!h^UH=sI56Vf@08Ux`FJ=P<-~Y>2@i(fYFxF3YK`r@E zRL2ilITeRe&PTP|XV*V7Ph&Ic&!Gl-9yNg9%totk&;GXdb0Ln58unHN_BThM4$nj@ zr2tDrRPHgf8&)ML)=a9vIJ8;pL{z9zyD{3s)9em>&dSp2I>1>ug3X1D)-=GqTI@&kkAUQBqk6Ugp&FXrV>82S7}6l zVjQ6~kC-3K@!t$;-{Y*DiF)OfriO4&VJV^Wl4W%|3sZ8PEYg9$noX52UMqA>A{#4(MhZF zJhRdk`_l4i`*o}g>wVwi#c8>@o~b$Mo*CY}3^zS}S$4i>qR*G(`>(S0c&BS&QOPT^ zJ=1cQq?I1IB@mnD%UYK0&GgL5^ZN2Ui8)zW-s~l{<#DSb2L}85e+>0+ZVZ&{tKVA_ z*sv=!mYZuzJN1|q98;iX-K9;HwM%=f3G3fbU3aOh`eIpSpsuXpP)*>&LL1hl&08C4 zYHq$zd)9L|e~t ByKn#i delta 3576 zcmaLZdra0<9LMqVAc{~~+`N?HBZ7EKB{R$nFt15?AuoB$G{hTfspKW;5xfB2AP`L{ zP0}V?P1>_e#Y&^8ZOxgMsau)Z=GK;@o0~OS@6Ye~vh`PIexBDkzu)gU=lss^{2siJ z{ngmO_c7tsj&gu>CP}TGyN-RM_@ErV&p8gcI=lyuU>j_}R`?ml;u*XbuVGufW$h;P z({9H8n9$C-emD-poeQ`^D*9qEcEfV?;|HM&+(nF}{VhI#H&Ao?4fVZdYe(H5Iv$U7 z?EI*SCSwft#SWN(aX1y*GQP{V3ks0FTq!bHw;LnykR5*?HSkFsif2&+g)=KnFcN!U zENb8($UirXk4~6l?R?brg&4*7u7pYoR-%^f1jb_{Y64d=5pSTr7#K$wb}Ad{jRLs5>u2^;d}jec?kY9q|-u=2xx#18T|cVlqavj#{BK)ODj!6V5iL zU_aWkQ8%;$wL(Wx6KFt9pb=B?N(}4Yl}Z#lNK4ckwb@3X1{#YRU>fR9=i2#vWHH=w zWNvN)Zo_KS_YxUJdn46MM@={j8QbMpdtMytuO-UofM&WDHPe7ySb};Kd#zoMx~>s5 zp>r697p?sb>PD{PV!UhT=h2DYmIbK(^7+t&iUU-1hh?Z4SE2^kkLu_kK7^l`*HDk_ z4t7Cb`_NK%MLpBe$i8%oQ2nh%t!N4A#i2ApgP)$nsEhcfL&OI z`*8^NVy9{|=Ay3Kg6g;eS#4K?y3=~p_m80_bQ-nS&fEFh*hcUF9V#iDXhtn{GV88q zH4MAsNYoG0LJadULDU`Wcres)HL6`})}d~w9<{`0P!qUp-b99SP1ud`T_mF>VINdS z6Hs56iW)fA+-&C$+xa8rN%ITyvUwA=GEJzJ{TtQ4e&^MH1P1ghMJ@XT&NAenoEHg>_;5)j=1wvIg#LrlRhA zu(hY7uA77Ecqt~}YSgCNZRg)H>roT_*gS{o?~Nl{6itgZLJ5Yq0K&iEB z%v#g{b>>mC5jBwu*1m@7_!g?)+o&7)2ghR^%b@eQ$Xgb0i>YY9Wp<+2EJN?Twss9_ z$!pC9WJ9~JQ4?#jb~6s7-HD$=U7w9QpJ%Q>26pSwd;d35(FC@d`@9qU2gE#v>flrJ zOVnPtYVBXlzfda?!E@9dMx$1squCSH&tP+;3~(TaioP)0%tI~N64ZOU!H$=j<@gfE zccC_I1UpQ3+8@==7}P-H&6%jZvk*1GRn{)TfS&{9RP@DqY=s{otLPd~OZ=Ukzl$1B zFLh7oi9TGYV-)t9_rA~fTI?y*!1{Z#nd~7i5S4sVrsuC+s-j1r9|aY?)45)azY92; zOtiM(Z;)4p^4XgVCp(EZIh;dOo+h)rTIfF}BdJ$eI~qqZzS~XZb@Hs8SZcP$abyrF zC7X!KHnPC0@n~>6(Q3^lm1Hq_o@kHgF|?E?s6>z@c7VTUZknF|b40I39#P35tI1Z< zhdfN?ku5}J6475ey&XHqf6Fo&-N|60&G&!hZB7Q(^Py*~a)7)_YSgg8A3JYPw6q_w zN?&9c7@LXJWL2o`eQxA4l1wMFNfAjSZHb>u zAa9br#08Vv#k8)P9J?ZTDfXZ*SQ~%aSGA|ZPr;oX3nHr0{5ip${x!Z}M&cD;RZ`OR KVEg0~zJCGXs53GE diff --git a/frontend/src/language/zh_CN/app.po b/frontend/src/language/zh_CN/app.po index b33e08a6b..3beda9dd5 100644 --- a/frontend/src/language/zh_CN/app.po +++ b/frontend/src/language/zh_CN/app.po @@ -12,16 +12,15 @@ msgstr "" "Generated-By: easygettext\n" "X-Generator: Poedit 3.2.2\n" -#: src/routes/index.ts:125 +#: src/routes/index.ts:135 msgid "About" msgstr "关于" -#: src/routes/index.ts:100 src/views/domain/ngx_conf/LogEntry.vue:64 +#: src/routes/index.ts:110 src/views/domain/ngx_conf/LogEntry.vue:64 msgid "Access Logs" msgstr "访问日志" -#: src/views/config/Config.vue:24 src/views/domain/DomainList.vue:47 -#: src/views/user/User.vue:43 +#: src/views/domain/DomainList.vue:47 src/views/user/User.vue:43 msgid "Action" msgstr "操作" @@ -56,7 +55,7 @@ msgstr "高级模式" msgid "Are you sure you want to delete?" msgstr "您确定要删除吗?" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:27 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:16 msgid "Are you sure you want to remove this directive?" msgstr "您确定要删除这条指令?" @@ -64,7 +63,8 @@ msgstr "您确定要删除这条指令?" msgid "Are you sure you want to remove this location?" msgstr "您确定要删除这个 Location?" -#: src/views/preference/Preference.vue:7 src/views/preference/Preference.vue:8 +#: src/views/preference/Preference.vue:22 +#: src/views/preference/Preference.vue:23 msgid "Auto" msgstr "自动" @@ -80,7 +80,10 @@ msgstr "成功关闭 %{name} 自动续签" msgid "Auto-renewal enabled for %{name}" msgstr "成功启用 %{name} 自动续签" -#: src/views/domain/DomainEdit.vue:187 src/views/nginx_log/NginxLog.vue:173 +#: src/views/config/Config.vue:14 src/views/config/Config.vue:15 +#: src/views/config/Config.vue:25 src/views/config/Config.vue:5 +#: src/views/config/ConfigEdit.vue:55 src/views/domain/DomainEdit.vue:187 +#: src/views/nginx_log/NginxLog.vue:173 msgid "Back" msgstr "返回" @@ -111,7 +114,6 @@ msgstr "构建基于" #: src/components/StdDataDisplay/StdCurd.vue:27 #: src/components/StdDataEntry/components/StdSelector.vue:11 #: src/components/StdDataEntry/compontents/StdSelector.vue:11 -#: src/views/config/ConfigEdit.vue:49 msgid "Cancel" msgstr "取消" @@ -127,7 +129,7 @@ msgstr "此证书有效" msgid "Certificate Status" msgstr "证书状态" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:41 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:30 #: src/views/domain/ngx_conf/LocationEditor.vue:31 #: src/views/domain/ngx_conf/LocationEditor.vue:47 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 @@ -146,6 +148,7 @@ msgstr "配置" msgid "Configure SSL" msgstr "配置 SSL" +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:33 #: src/views/domain/ngx_conf/LocationEditor.vue:37 #: src/views/domain/ngx_conf/LocationEditor.vue:53 msgid "Content" @@ -171,8 +174,8 @@ msgstr "创建时间" msgid "Creating client facilitates communication with the CA server" msgstr "正在创建客户端用于与 CA 服务器通信" -#: src/views/preference/Preference.vue:13 -#: src/views/preference/Preference.vue:14 +#: src/views/preference/Preference.vue:28 +#: src/views/preference/Preference.vue:29 msgid "Dark" msgstr "深色" @@ -237,7 +240,7 @@ msgstr "域名配置文件创建成功" msgid "Edit %{n}" msgstr "编辑 %{n}" -#: src/routes/index.ts:78 src/views/config/ConfigEdit.vue:2 +#: src/routes/index.ts:88 src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "编辑配置" @@ -277,7 +280,7 @@ msgstr "启用成功" msgid "Encrypt website with Let's Encrypt" msgstr "用 Let's Encrypt 对网站进行加密" -#: src/routes/index.ts:104 src/views/domain/ngx_conf/LogEntry.vue:68 +#: src/routes/index.ts:114 src/views/domain/ngx_conf/LogEntry.vue:68 msgid "Error Logs" msgstr "错误日志" @@ -333,7 +336,15 @@ msgstr "正在获取证书,请稍等..." msgid "Home" msgstr "首页" -#: src/routes/index.ts:135 src/views/other/Install.vue:128 +#: src/views/preference/Preference.vue:17 +msgid "HTTP Challenge Port" +msgstr "HTTP Challenge 监听端口" + +#: src/views/preference/Preference.vue:5 +msgid "HTTP Port" +msgstr "HTTP 监听端口" + +#: src/routes/index.ts:145 src/views/other/Install.vue:128 msgid "Install" msgstr "安装" @@ -349,12 +360,16 @@ msgstr "中级证书颁发机构: %{issuer}" msgid "Issued certificate successfully" msgstr "证书申请成功" +#: src/views/preference/Preference.vue:11 +msgid "Jwt Secret" +msgstr "Jwt 密钥" + #: src/views/user/User.vue:26 msgid "Leave blank for no change" msgstr "留空表示不修改" -#: src/views/preference/Preference.vue:10 -#: src/views/preference/Preference.vue:11 +#: src/views/preference/Preference.vue:25 +#: src/views/preference/Preference.vue:26 msgid "Light" msgstr "浅色" @@ -372,7 +387,7 @@ msgstr "Location" msgid "Locations" msgstr "Locations" -#: src/routes/index.ts:141 src/views/other/Login.vue:103 +#: src/routes/index.ts:151 src/views/other/Login.vue:103 msgid "Login" msgstr "登录" @@ -392,7 +407,7 @@ msgstr "" "在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 " "HTTPChallengePort (默认: 9180)" -#: src/routes/index.ts:69 +#: src/routes/index.ts:69 src/routes/index.ts:78 msgid "Manage Configs" msgstr "配置管理" @@ -425,8 +440,7 @@ msgstr "修改" msgid "Modify Config" msgstr "修改配置文件" -#: src/views/config/Config.vue:12 src/views/domain/DomainEdit.vue:36 -#: src/views/domain/DomainList.vue:15 +#: src/views/domain/DomainEdit.vue:36 src/views/domain/DomainList.vue:15 msgid "Name" msgstr "名称" @@ -450,18 +464,26 @@ msgstr "上传流量" msgid "Next" msgstr "下一步" -#: src/routes/index.ts:94 src/views/nginx_log/NginxLog.vue:2 +#: src/views/preference/Preference.vue:33 +msgid "Nginx Access Log Path" +msgstr "Nginx 访问日志路径" + +#: src/views/preference/Preference.vue:36 +msgid "Nginx Error Log Path" +msgstr "Nginx 错误日志路径" + +#: src/routes/index.ts:104 src/views/nginx_log/NginxLog.vue:2 msgid "Nginx Log" msgstr "Nginx 日志" #: src/components/StdDataDisplay/StdTable.vue:52 #: src/views/domain/DomainList.vue:24 -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:18 #: src/views/domain/ngx_conf/LocationEditor.vue:21 msgid "No" msgstr "取消" -#: src/routes/index.ts:147 src/routes/index.ts:149 +#: src/routes/index.ts:157 src/routes/index.ts:159 msgid "Not Found" msgstr "找不到页面" @@ -521,7 +543,7 @@ msgstr "请输入您的密码!" msgid "Please input your username!" msgstr "请输入您的用户名!" -#: src/routes/index.ts:117 src/views/preference/Preference.vue:2 +#: src/routes/index.ts:127 src/views/preference/Preference.vue:2 msgid "Preference" msgstr "偏好设置" @@ -563,9 +585,17 @@ msgstr "正在重载 Nginx" msgid "Reset" msgstr "重置" -#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:190 -#: src/views/preference/Preference.vue:22 -#: src/views/preference/Preference.vue:23 +#: src/views/preference/Preference.vue:8 +msgid "Run Mode" +msgstr "运行模式" + +#: src/views/config/ConfigEdit.vue:58 src/views/domain/DomainEdit.vue:190 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:30 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:31 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:36 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37 +#: src/views/preference/Preference.vue:43 +#: src/views/preference/Preference.vue:44 msgid "Save" msgstr "保存" @@ -575,11 +605,13 @@ msgstr "保存" msgid "Save Directive" msgstr "保存指令" -#: src/views/config/ConfigEdit.vue:36 src/views/domain/DomainAdd.vue:54 +#: src/views/config/ConfigEdit.vue:42 src/views/domain/DomainAdd.vue:54 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37 msgid "Save error %{msg}" msgstr "保存错误 %{msg}" #: src/components/StdDataDisplay/StdBatchEdit.vue:40 +#: src/views/preference/Preference.vue:39 msgid "Save successfully" msgstr "保存成功" @@ -587,8 +619,9 @@ msgstr "保存成功" msgid "Save Successfully" msgstr "保存成功" -#: src/views/config/ConfigEdit.vue:34 src/views/domain/DomainAdd.vue:43 +#: src/views/config/ConfigEdit.vue:40 src/views/domain/DomainAdd.vue:43 #: src/views/domain/DomainEdit.vue:97 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:35 msgid "Saved successfully" msgstr "保存成功" @@ -605,10 +638,10 @@ msgstr "上传" #: src/components/StdDataDisplay/StdTable.vue:168 #: src/components/StdDataDisplay/StdTable.vue:343 #: src/components/StdDataDisplay/StdTable.vue:463 -#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:100 +#: src/views/config/ConfigEdit.vue:28 src/views/domain/DomainEdit.vue:100 #: src/views/domain/DomainEdit.vue:62 src/views/domain/DomainEdit.vue:74 #: src/views/domain/DomainEdit.vue:83 src/views/domain/DomainList.vue:83 -#: src/views/other/Install.vue:71 +#: src/views/other/Install.vue:71 src/views/preference/Preference.vue:41 msgid "Server error" msgstr "服务器错误" @@ -629,7 +662,7 @@ msgstr "必须为 server_name 指令指明参数" msgid "Single Directive" msgstr "单行指令" -#: src/routes/index.ts:108 +#: src/routes/index.ts:118 msgid "Site Logs" msgstr "站点列表" @@ -657,10 +690,14 @@ msgstr "Swap" msgid "Table" msgstr "列表" -#: src/routes/index.ts:86 src/views/pty/Terminal.vue:2 +#: src/routes/index.ts:96 src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "终端" +#: src/views/preference/Preference.vue:14 +msgid "Terminal Start Command" +msgstr "终端启动命令" + #: src/views/domain/cert/IssueCert.vue:205 msgid "" "The certificate for the domain will be checked every hour, and will be " @@ -676,12 +713,11 @@ msgstr "文件名不能包含以下字符: %{c}" msgid "The username or password is incorrect" msgstr "用户名或密码错误" -#: src/views/preference/Preference.vue:5 +#: src/views/preference/Preference.vue:20 msgid "Theme" msgstr "主题" -#: src/views/config/Config.vue:17 src/views/domain/DomainList.vue:41 -#: src/views/user/User.vue:37 +#: src/views/domain/DomainList.vue:41 src/views/user/User.vue:37 msgid "Updated at" msgstr "修改时间" @@ -722,7 +758,7 @@ msgstr "正在将证书私钥写入磁盘" msgid "Writing certificate to disk" msgstr "正在将证书写入磁盘" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:28 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:17 #: src/views/domain/ngx_conf/LocationEditor.vue:20 msgid "Yes" msgstr "是的" @@ -783,9 +819,6 @@ msgstr "开源许可" #~ msgid "Certificate Path (ssl_certificate)" #~ msgstr "TLS 证书路径 (ssl_certificate)" -#~ msgid "HTTP Listen Port" -#~ msgstr "HTTP 监听端口" - #~ msgid "HTTPS Listen Port" #~ msgstr "HTTPS 监听端口" diff --git a/frontend/src/language/zh_TW/app.po b/frontend/src/language/zh_TW/app.po index 4719d4264..d408649fa 100644 --- a/frontend/src/language/zh_TW/app.po +++ b/frontend/src/language/zh_TW/app.po @@ -13,16 +13,15 @@ msgstr "" "Generated-By: easygettext\n" "X-Generator: Poedit 3.2.2\n" -#: src/routes/index.ts:125 +#: src/routes/index.ts:135 msgid "About" msgstr "關於" -#: src/routes/index.ts:100 src/views/domain/ngx_conf/LogEntry.vue:64 +#: src/routes/index.ts:110 src/views/domain/ngx_conf/LogEntry.vue:64 msgid "Access Logs" msgstr "訪問日誌" -#: src/views/config/Config.vue:24 src/views/domain/DomainList.vue:47 -#: src/views/user/User.vue:43 +#: src/views/domain/DomainList.vue:47 src/views/user/User.vue:43 msgid "Action" msgstr "操作" @@ -57,7 +56,7 @@ msgstr "高階模式" msgid "Are you sure you want to delete?" msgstr "你確定你要刪除?" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:27 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:16 msgid "Are you sure you want to remove this directive?" msgstr "您確定要刪除這條指令?" @@ -65,7 +64,8 @@ msgstr "您確定要刪除這條指令?" msgid "Are you sure you want to remove this location?" msgstr "您確定要刪除此 Location 嗎?" -#: src/views/preference/Preference.vue:7 src/views/preference/Preference.vue:8 +#: src/views/preference/Preference.vue:22 +#: src/views/preference/Preference.vue:23 msgid "Auto" msgstr "自動" @@ -81,7 +81,10 @@ msgstr "已關閉 %{name} 自動續簽" msgid "Auto-renewal enabled for %{name}" msgstr "已啟用 %{name} 自動續簽" -#: src/views/domain/DomainEdit.vue:187 src/views/nginx_log/NginxLog.vue:173 +#: src/views/config/Config.vue:14 src/views/config/Config.vue:15 +#: src/views/config/Config.vue:25 src/views/config/Config.vue:5 +#: src/views/config/ConfigEdit.vue:55 src/views/domain/DomainEdit.vue:187 +#: src/views/nginx_log/NginxLog.vue:173 msgid "Back" msgstr "返回" @@ -112,7 +115,6 @@ msgstr "構建基於" #: src/components/StdDataDisplay/StdCurd.vue:27 #: src/components/StdDataEntry/components/StdSelector.vue:11 #: src/components/StdDataEntry/compontents/StdSelector.vue:11 -#: src/views/config/ConfigEdit.vue:49 msgid "Cancel" msgstr "取消" @@ -128,7 +130,7 @@ msgstr "此憑證有效" msgid "Certificate Status" msgstr "憑證狀態" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:41 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:30 #: src/views/domain/ngx_conf/LocationEditor.vue:31 #: src/views/domain/ngx_conf/LocationEditor.vue:47 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 @@ -147,6 +149,7 @@ msgstr "配置" msgid "Configure SSL" msgstr "配置 SSL" +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:33 #: src/views/domain/ngx_conf/LocationEditor.vue:37 #: src/views/domain/ngx_conf/LocationEditor.vue:53 msgid "Content" @@ -172,8 +175,8 @@ msgstr "建立時間" msgid "Creating client facilitates communication with the CA server" msgstr "創建客戶端方便與CA服務器通信" -#: src/views/preference/Preference.vue:13 -#: src/views/preference/Preference.vue:14 +#: src/views/preference/Preference.vue:28 +#: src/views/preference/Preference.vue:29 msgid "Dark" msgstr "深色" @@ -238,7 +241,7 @@ msgstr "域名配置文件創建成功" msgid "Edit %{n}" msgstr "編輯 %{n}" -#: src/routes/index.ts:78 src/views/config/ConfigEdit.vue:2 +#: src/routes/index.ts:88 src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "編輯配置" @@ -278,7 +281,7 @@ msgstr "啟用成功" msgid "Encrypt website with Let's Encrypt" msgstr "用 Let's Encrypt 對網站進行加密" -#: src/routes/index.ts:104 src/views/domain/ngx_conf/LogEntry.vue:68 +#: src/routes/index.ts:114 src/views/domain/ngx_conf/LogEntry.vue:68 msgid "Error Logs" msgstr "錯誤日志" @@ -334,7 +337,17 @@ msgstr "正在獲取憑證,請稍等..." msgid "Home" msgstr "首頁" -#: src/routes/index.ts:135 src/views/other/Install.vue:128 +#: src/views/preference/Preference.vue:17 +#, fuzzy +msgid "HTTP Challenge Port" +msgstr "HTTP 監聽埠" + +#: src/views/preference/Preference.vue:5 +#, fuzzy +msgid "HTTP Port" +msgstr "HTTP 監聽埠" + +#: src/routes/index.ts:145 src/views/other/Install.vue:128 msgid "Install" msgstr "安裝" @@ -350,12 +363,16 @@ msgstr "中級憑證頒發機構: %{issuer}" msgid "Issued certificate successfully" msgstr "頒發證書成功" +#: src/views/preference/Preference.vue:11 +msgid "Jwt Secret" +msgstr "" + #: src/views/user/User.vue:26 msgid "Leave blank for no change" msgstr "留空表示不修改" -#: src/views/preference/Preference.vue:10 -#: src/views/preference/Preference.vue:11 +#: src/views/preference/Preference.vue:25 +#: src/views/preference/Preference.vue:26 msgid "Light" msgstr "淺色" @@ -373,7 +390,7 @@ msgstr "Location" msgid "Locations" msgstr "Locations" -#: src/routes/index.ts:141 src/views/other/Login.vue:103 +#: src/routes/index.ts:151 src/views/other/Login.vue:103 msgid "Login" msgstr "登入" @@ -393,7 +410,7 @@ msgstr "" "在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 " "HTTPChallengePort (預設: 9180)" -#: src/routes/index.ts:69 +#: src/routes/index.ts:69 src/routes/index.ts:78 msgid "Manage Configs" msgstr "配置管理" @@ -426,8 +443,7 @@ msgstr "修改" msgid "Modify Config" msgstr "修改配置" -#: src/views/config/Config.vue:12 src/views/domain/DomainEdit.vue:36 -#: src/views/domain/DomainList.vue:15 +#: src/views/domain/DomainEdit.vue:36 src/views/domain/DomainList.vue:15 msgid "Name" msgstr "名稱" @@ -451,18 +467,28 @@ msgstr "上傳流量" msgid "Next" msgstr "下一步" -#: src/routes/index.ts:94 src/views/nginx_log/NginxLog.vue:2 +#: src/views/preference/Preference.vue:33 +#, fuzzy +msgid "Nginx Access Log Path" +msgstr "訪問日誌" + +#: src/views/preference/Preference.vue:36 +#, fuzzy +msgid "Nginx Error Log Path" +msgstr "Nginx 日誌" + +#: src/routes/index.ts:104 src/views/nginx_log/NginxLog.vue:2 msgid "Nginx Log" msgstr "Nginx 日誌" #: src/components/StdDataDisplay/StdTable.vue:52 #: src/views/domain/DomainList.vue:24 -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:18 #: src/views/domain/ngx_conf/LocationEditor.vue:21 msgid "No" msgstr "取消" -#: src/routes/index.ts:147 src/routes/index.ts:149 +#: src/routes/index.ts:157 src/routes/index.ts:159 msgid "Not Found" msgstr "找不到頁面" @@ -522,7 +548,7 @@ msgstr "請輸入您的密碼!" msgid "Please input your username!" msgstr "請輸入您的使用者名稱!" -#: src/routes/index.ts:117 src/views/preference/Preference.vue:2 +#: src/routes/index.ts:127 src/views/preference/Preference.vue:2 msgid "Preference" msgstr "設定" @@ -564,9 +590,18 @@ msgstr "重载 Nginx" msgid "Reset" msgstr "重設" -#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:190 -#: src/views/preference/Preference.vue:22 -#: src/views/preference/Preference.vue:23 +#: src/views/preference/Preference.vue:8 +#, fuzzy +msgid "Run Mode" +msgstr "高階模式" + +#: src/views/config/ConfigEdit.vue:58 src/views/domain/DomainEdit.vue:190 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:30 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:31 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:36 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37 +#: src/views/preference/Preference.vue:43 +#: src/views/preference/Preference.vue:44 msgid "Save" msgstr "儲存" @@ -576,11 +611,13 @@ msgstr "儲存" msgid "Save Directive" msgstr "儲存指令" -#: src/views/config/ConfigEdit.vue:36 src/views/domain/DomainAdd.vue:54 +#: src/views/config/ConfigEdit.vue:42 src/views/domain/DomainAdd.vue:54 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37 msgid "Save error %{msg}" msgstr "儲存錯誤 %{msg}" #: src/components/StdDataDisplay/StdBatchEdit.vue:40 +#: src/views/preference/Preference.vue:39 msgid "Save successfully" msgstr "保存成功" @@ -588,8 +625,9 @@ msgstr "保存成功" msgid "Save Successfully" msgstr "保存成功" -#: src/views/config/ConfigEdit.vue:34 src/views/domain/DomainAdd.vue:43 +#: src/views/config/ConfigEdit.vue:40 src/views/domain/DomainAdd.vue:43 #: src/views/domain/DomainEdit.vue:97 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:35 msgid "Saved successfully" msgstr "儲存成功" @@ -606,10 +644,10 @@ msgstr "上傳" #: src/components/StdDataDisplay/StdTable.vue:168 #: src/components/StdDataDisplay/StdTable.vue:343 #: src/components/StdDataDisplay/StdTable.vue:463 -#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:100 +#: src/views/config/ConfigEdit.vue:28 src/views/domain/DomainEdit.vue:100 #: src/views/domain/DomainEdit.vue:62 src/views/domain/DomainEdit.vue:74 #: src/views/domain/DomainEdit.vue:83 src/views/domain/DomainList.vue:83 -#: src/views/other/Install.vue:71 +#: src/views/other/Install.vue:71 src/views/preference/Preference.vue:41 msgid "Server error" msgstr "伺服器錯誤" @@ -630,7 +668,7 @@ msgstr "必須為 server_name 指令指明參數" msgid "Single Directive" msgstr "單行指令" -#: src/routes/index.ts:108 +#: src/routes/index.ts:118 msgid "Site Logs" msgstr "網站日誌" @@ -658,10 +696,14 @@ msgstr "交換空間" msgid "Table" msgstr "表格" -#: src/routes/index.ts:86 src/views/pty/Terminal.vue:2 +#: src/routes/index.ts:96 src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "終端" +#: src/views/preference/Preference.vue:14 +msgid "Terminal Start Command" +msgstr "" + #: src/views/domain/cert/IssueCert.vue:205 msgid "" "The certificate for the domain will be checked every hour, and will be " @@ -678,12 +720,11 @@ msgstr "檔名不能包含以下字元: %{c}" msgid "The username or password is incorrect" msgstr "用戶名或密碼不正確" -#: src/views/preference/Preference.vue:5 +#: src/views/preference/Preference.vue:20 msgid "Theme" msgstr "外觀樣式" -#: src/views/config/Config.vue:17 src/views/domain/DomainList.vue:41 -#: src/views/user/User.vue:37 +#: src/views/domain/DomainList.vue:41 src/views/user/User.vue:37 msgid "Updated at" msgstr "修改時間" @@ -724,7 +765,7 @@ msgstr "將證書私鑰寫入磁盤" msgid "Writing certificate to disk" msgstr "將證書寫入磁盤" -#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:28 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:17 #: src/views/domain/ngx_conf/LocationEditor.vue:20 msgid "Yes" msgstr "是的" @@ -777,9 +818,6 @@ msgstr "開源軟體授權條款" #~ msgid "Certificate Path (ssl_certificate)" #~ msgstr "TLS 證書路徑 (ssl_certificate)" -#~ msgid "HTTP Listen Port" -#~ msgstr "HTTP 監聽埠" - #~ msgid "HTTPS Listen Port" #~ msgstr "HTTPS 監聽埠" From a5b9bb88d6f01b5ece512072205bf7285e8aa26f Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Tue, 3 Jan 2023 00:24:51 +0800 Subject: [PATCH 11/22] wip: ssl manage panel #52, #29 --- frontend/src/api/cert.ts | 5 + frontend/src/api/domain.ts | 6 +- frontend/src/language/en/app.po | 21 +- frontend/src/language/messages.pot | 16 + frontend/src/language/translations.json | 2 +- frontend/src/language/zh_CN/app.mo | Bin 9936 -> 10027 bytes frontend/src/language/zh_CN/app.po | 21 +- frontend/src/language/zh_TW/app.po | 21 +- frontend/src/routes/index.ts | 11 +- frontend/src/version.json | 2 +- frontend/src/views/cert/Cert.vue | 88 +++ .../views/config/{config.tsx => config.ts} | 1 - frontend/src/views/template/Template.vue | 11 + frontend/version.json | 2 +- server/api/cert.go | 109 ++- server/api/domain.go | 650 +++++++++--------- server/model/cert.go | 32 +- server/router/routers.go | 9 +- 18 files changed, 667 insertions(+), 340 deletions(-) create mode 100644 frontend/src/api/cert.ts create mode 100644 frontend/src/views/cert/Cert.vue rename frontend/src/views/config/{config.tsx => config.ts} (96%) create mode 100644 frontend/src/views/template/Template.vue diff --git a/frontend/src/api/cert.ts b/frontend/src/api/cert.ts new file mode 100644 index 000000000..6edf2470f --- /dev/null +++ b/frontend/src/api/cert.ts @@ -0,0 +1,5 @@ +import Curd from '@/api/curd' + +const cert = new Curd('/cert') + +export default cert diff --git a/frontend/src/api/domain.ts b/frontend/src/api/domain.ts index 0e6b55ab7..ce927e075 100644 --- a/frontend/src/api/domain.ts +++ b/frontend/src/api/domain.ts @@ -13,13 +13,13 @@ class Domain extends Curd { get_template() { return http.get('template') } - + add_auto_cert(domain: string) { - return http.post('cert/' + domain) + return http.post('auto_cert/' + domain) } remove_auto_cert(domain: string) { - return http.delete('cert/' + domain) + return http.delete('auto_cert/' + domain) } } diff --git a/frontend/src/language/en/app.po b/frontend/src/language/en/app.po index 303d0066a..be5d523ee 100644 --- a/frontend/src/language/en/app.po +++ b/frontend/src/language/en/app.po @@ -17,7 +17,8 @@ msgstr "About" msgid "Access Logs" msgstr "" -#: src/views/domain/DomainList.vue:47 src/views/user/User.vue:43 +#: src/views/config/config.ts:36 src/views/domain/DomainList.vue:47 +#: src/views/user/User.vue:43 msgid "Action" msgstr "Action" @@ -205,6 +206,10 @@ msgstr "" msgid "Development Mode" msgstr "Development Mode" +#: src/views/config/config.ts:20 +msgid "Dir" +msgstr "" + #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:20 msgid "Directive" msgstr "Directive" @@ -308,6 +313,10 @@ msgstr "Failed to enable %{msg}" msgid "Failed to get certificate information" msgstr "" +#: src/views/config/config.ts:22 +msgid "File" +msgstr "" + #: src/views/other/Error.vue:3 src/views/other/Error.vue:4 msgid "File Not Found" msgstr "File Not Found" @@ -444,7 +453,8 @@ msgstr "Modify Config" msgid "Modify Config" msgstr "Modify Config" -#: src/views/domain/DomainEdit.vue:36 src/views/domain/DomainList.vue:15 +#: src/views/config/config.ts:9 src/views/domain/DomainEdit.vue:36 +#: src/views/domain/DomainList.vue:15 msgid "Name" msgstr "Name" @@ -730,7 +740,12 @@ msgstr "" msgid "Theme" msgstr "" -#: src/views/domain/DomainList.vue:41 src/views/user/User.vue:37 +#: src/language/constants.ts:23 src/views/config/config.ts:14 +msgid "Type" +msgstr "" + +#: src/views/config/config.ts:29 src/views/domain/DomainList.vue:41 +#: src/views/user/User.vue:37 msgid "Updated at" msgstr "Updated at" diff --git a/frontend/src/language/messages.pot b/frontend/src/language/messages.pot index 18fa02338..847ab7823 100644 --- a/frontend/src/language/messages.pot +++ b/frontend/src/language/messages.pot @@ -11,6 +11,7 @@ msgstr "" msgid "Access Logs" msgstr "" +#: src/views/config/config.ts:36 #: src/views/domain/DomainList.vue:47 #: src/views/user/User.vue:43 msgid "Action" @@ -203,6 +204,10 @@ msgstr "" msgid "Development Mode" msgstr "" +#: src/views/config/config.ts:20 +msgid "Dir" +msgstr "" + #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:20 msgid "Directive" msgstr "" @@ -320,6 +325,10 @@ msgstr "" msgid "Failed to get certificate information" msgstr "" +#: src/views/config/config.ts:22 +msgid "File" +msgstr "" + #: src/views/other/Error.vue:3 #: src/views/other/Error.vue:4 msgid "File Not Found" @@ -456,6 +465,7 @@ msgstr "" msgid "Modify Config" msgstr "" +#: src/views/config/config.ts:9 #: src/views/domain/DomainEdit.vue:36 #: src/views/domain/DomainList.vue:15 msgid "Name" @@ -747,6 +757,12 @@ msgstr "" msgid "Theme" msgstr "" +#: src/language/constants.ts:23 +#: src/views/config/config.ts:14 +msgid "Type" +msgstr "" + +#: src/views/config/config.ts:29 #: src/views/domain/DomainList.vue:41 #: src/views/user/User.vue:37 msgid "Updated at" diff --git a/frontend/src/language/translations.json b/frontend/src/language/translations.json index bd22dd781..7ac418fdf 100644 --- a/frontend/src/language/translations.json +++ b/frontend/src/language/translations.json @@ -1 +1 @@ -{"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Auto":"自动","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Comments":"注释","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Development Mode":"开发模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Domain Config Created Successfully":"域名配置文件创建成功","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","HTTP Challenge Port":"HTTP Challenge 监听端口","HTTP Port":"HTTP 监听端口","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Jwt Secret":"Jwt 密钥","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","Next":"下一步","Nginx Access Log Path":"Nginx 访问日志路径","Nginx Error Log Path":"Nginx 错误日志路径","Nginx Log":"Nginx 日志","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:当前配置中的 server_name 必须为需要申请证书的域名。","Obtaining certificate":"正在获取证书","OK":"确定","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reloading nginx":"正在重载 Nginx","Reset":"重置","Run Mode":"运行模式","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","Table":"列表","Terminal":"终端","Terminal Start Command":"终端启动命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Updated at":"修改时间","Updated successfully":"更新成功","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","License":{"Project":"开源许可"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"Note: The server_name in the current configuration must be the domain name you need to get the certificate.","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}},"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Auto":"自動","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Comments":"註釋","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Development Mode":"開發模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Domain Config Created Successfully":"域名配置文件創建成功","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error Logs":"錯誤日志","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","Next":"下一步","Nginx Log":"Nginx 日誌","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:當前配置中的 server_name 必須為需要申請證書的域名。","Obtaining certificate":"正在獲取證書,請稍等...","OK":"確定","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reloading nginx":"重载 Nginx","Reset":"重設","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","Table":"表格","Terminal":"終端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Updated at":"修改時間","Updated successfully":"已成功更新","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","License":{"Project":"開源軟體授權條款"}}} \ No newline at end of file +{"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Auto":"自动","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Comments":"注释","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Development Mode":"开发模式","Dir":"目录","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Domain Config Created Successfully":"域名配置文件创建成功","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","File":"文件","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","HTTP Challenge Port":"HTTP Challenge 监听端口","HTTP Port":"HTTP 监听端口","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Jwt Secret":"Jwt 密钥","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","Next":"下一步","Nginx Access Log Path":"Nginx 访问日志路径","Nginx Error Log Path":"Nginx 错误日志路径","Nginx Log":"Nginx 日志","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:当前配置中的 server_name 必须为需要申请证书的域名。","Obtaining certificate":"正在获取证书","OK":"确定","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reloading nginx":"正在重载 Nginx","Reset":"重置","Run Mode":"运行模式","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","Table":"列表","Terminal":"终端","Terminal Start Command":"终端启动命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Type":"类型","Updated at":"修改时间","Updated successfully":"更新成功","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","License":{"Project":"开源许可"}},"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Auto":"自動","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Comments":"註釋","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Development Mode":"開發模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Domain Config Created Successfully":"域名配置文件創建成功","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error Logs":"錯誤日志","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","Next":"下一步","Nginx Log":"Nginx 日誌","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:當前配置中的 server_name 必須為需要申請證書的域名。","Obtaining certificate":"正在獲取證書,請稍等...","OK":"確定","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reloading nginx":"重载 Nginx","Reset":"重設","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","Table":"表格","Terminal":"終端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Updated at":"修改時間","Updated successfully":"已成功更新","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","License":{"Project":"開源軟體授權條款"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"Note: The server_name in the current configuration must be the domain name you need to get the certificate.","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}}} \ No newline at end of file diff --git a/frontend/src/language/zh_CN/app.mo b/frontend/src/language/zh_CN/app.mo index 9c51b4baac0849389bc12bf9d45895bbbca0fe78..94ea7ba508ba35a6f01ce7108c5d099ad9d4b0f0 100644 GIT binary patch delta 3775 zcmZwJc~DkW9LDj(;wz{r;TFoK0xIS%l1QeZX{HcmTDco$MDC>GcGENyFjGTA5fjUG zv<#OqbF`*L$E9M-#&N=CN(Z&6Msvz0$Lagr_t#8+bcg5toO73R&OP_s_vM@6d$PUD z(cxu|Z4Zehh4q}fif0?}!8W0>bL?^xu^~>u0M5oRoR3X$F*d@r7=c@?z7rFvAH=Ts z9d^M$6X(L6^IRGQU6_Gwa4;rfe((fWjFHq=V-%L7#aLdIf6g4q`H%L*4oBs2RJ1I=?;(K?84W zwnRPaMAVJtAb)NyAG(2(rp&(@Dr1L6wh=Y5D(sGjF#)fm1{ldfO=UCGqU?eiKrd9s zS*V7G+3}I6M=%DN1UD5+(L-I=s5$emMbw&kmK{)cl7`%r%d~n9Y6?f92Aqc)a6an1 znaH18X7!Dz^Y+^QkC8szDbxUKF%;`O+i?SRXScBc8@C9aFdwy879oe+64U@UpzgR5 zHSis%4iBK(IfAY6y!jhy1{?AmK2B8L!i|TM3YRaag?w|-Y z1IthYD?!c7I#fHmPy^qG8rT8k=G`$|iQi%dj$@jV_5PPr&;`d)4Sb2}=rrn?T|jko z1J&Ry)ByiREzXEm!Q&lJ1M7yG+H}+-7>{~{3$Pt}s4u#080v-4Aq8D{inG=5*QomU z=1-_Qyn&i}eNXGWC^HVZDVK_BI17_-GOC?o)cI@dc%^v)J)Q8Qop9a!!wh4k_#K&X zsF_Jc%~Trd`V2ch0QGFMQ3IW5$7kB{c~)PJYNs@g`BwuQ*r5w5?Zkbk_x~vB_%En6 za2u2Hp6ySH53Z3;$RxT<)PP5!uFEqE%vq=zDzf^fczge=*r5(SME=|nKC~Dwq8hwn z-b9W3o*BskP=n1-=k-Q)oMrW)sI@T4>K^J*mZHw9(hk1d+%EGN>RHy<2{%wPbJOY} ziNOma%qFO3-2yd`zQ{6hV^ObL5vrpSb1iD1<>)WQ?G*IPPNVLu7B#|as0;6*zWM6W zx>kQv)J(;qj;Ej+>}+P>Lh6I9{)Jg%UPfK_Gjd~|yJb5<`4-YZB2g#An(a^>q?+mG zK-55TQ8PB$EVSdRQ0;6)&EQtljqS%AJn0|z_+?`r^nS*p2GACDVVaqVnwc!CXQMiN z#+-(l@)f9oZnOGF*pvEM)cJZ&Iv!)DU>NhrAbnWd;T zRBrXX<|n8bI*Dq(1~n5G&1>kX;X4#$J>D%Djk+MgOhHXuXAH+I+dst2K@EH)&cJ-s zs=tJ~^U#!Fd#%m3sD3)8@cdQi%?>THEcBnL)kk9@`|~k?#TbTbkY(e_P*Z;x19%?& zj6c8bkbUVtxKd8o;H^0!C$oJq7LCol2&Xd8CkN3nerC60a^c^vm@Bg6(`5Cy+Ys^!DIl##9}-0}$uQEMj3AGa zm&i(@Z7ms1c9G#^4bhfH^2w`Y9B~6CRd;H9A+-8#)bWt&L(yLa!bTL$s9qXV5gw@9 nwD0P%vg)|_B_Z|JuefsbP<2H@k3gVq|Iw?JCDrGW!$ST6buUO3 delta 3689 zcmYk;dr*{B7{~F$f`Dj*i1{1M2(!k|nOPq*NScDqeJk)(6nfqP#u+{23Uc~xDM6vA>_|}!AA$I zxAIj~`zDN_e;3x)x%)60wRD3p2D4BD$j5uJ2z6sQYDO!qyxrW38sI_HKt4xJ2Q{$csHOV>bqN1J4d6PeV-Gj$!L3l&V~|yK zamXZH4}1eNQ1_icotdA^OYK>I&Ey6Z4BFj7l_ObyEnN(1#GO$i?uu&H3;A}LPy?(&5AL$^d#H)|ykusPIcW{j?hL$E=}46uf*Q~S)Qk&JGnj_zumts> zQjEj3W-V$3>o6XFL~Y4+)ZWLjubg-1%^;%(=Af2vGHRwpsHL2VYPiU*SE2^88a05; zsHLq&E%|=)i1|Hg#TroeHKOkO5BWavx)4sD1`vhnFdnsJDX19?M6Ey;YG5N#E0c?Q z&0hX&@6a)@b^Wk2%E_E4R)jUz81AtA6xx-)Ytek^tHy-uesmPz3&4+%>RwS_gYOsk4S%Vt!0rL~o1CQDD z-%&Gdv~m;b3`B51bblYz7G|Q_jYqz#T!C4P+QM?wN^JF#QN#V_hvs3_-X28_;1aUk zu4Q82HA_O>H^9t54PZFx@a3YmXaQI=?$fQ(N25!4bLM>VKNJ@Bmg z8!o1N-O9y`O4rNGO4NOuP&2ExaxH2g2d#YE{1&<2>rMwUuEG2hHIOFMQibt#B@ckFjzA z_N82kYPZj>e`VHVF!dKu18qPJ;ELH~^-=6^YcCgK$*5r$RbY2>AnNc8w{pHY4Yfig zsQb!LD^YH)M?I&;JYar?YJbA4NB#b|vt&Z>nq9bI-a?Js!@F3FF{snN95wS=)B}&9 zIy_~bLmjTmsDU5Zgp_aVB8kC|s^kP@sjX}7BP8h-xc~azZP(fEY^5Ae7XEB7#$nayk`^Mn;fVigfjq!Rgr(s-hR7)BHjYc&6DWI_lXz;_89xN*ee#O>*2 zD{RE|#G6ECBA6IV=!a<&F`7_nL+C%E6~sUyig=o6PSeRO(fUs!T3GE$GXu8}Q;0sq zRH6&ficorp*hLH{mJ*AIM~Gg;Wa9ReMBzCi(JB|3eNoTxzj7n2awkr(e33a1qY3>~ wS6bb(*o|21D~vqn@ujyt9OU~q`kPQ+U570pzF7%NgM5E?>J{qimh1`oAD{?7VgLXD diff --git a/frontend/src/language/zh_CN/app.po b/frontend/src/language/zh_CN/app.po index 3beda9dd5..9cfc6551d 100644 --- a/frontend/src/language/zh_CN/app.po +++ b/frontend/src/language/zh_CN/app.po @@ -20,7 +20,8 @@ msgstr "关于" msgid "Access Logs" msgstr "访问日志" -#: src/views/domain/DomainList.vue:47 src/views/user/User.vue:43 +#: src/views/config/config.ts:36 src/views/domain/DomainList.vue:47 +#: src/views/user/User.vue:43 msgid "Action" msgstr "操作" @@ -204,6 +205,10 @@ msgstr "删除站点: %{site_name}" msgid "Development Mode" msgstr "开发模式" +#: src/views/config/config.ts:20 +msgid "Dir" +msgstr "目录" + #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:20 msgid "Directive" msgstr "指令" @@ -307,6 +312,10 @@ msgstr "启用失败 %{msg}" msgid "Failed to get certificate information" msgstr "获取证书信息失败" +#: src/views/config/config.ts:22 +msgid "File" +msgstr "文件" + #: src/views/other/Error.vue:3 src/views/other/Error.vue:4 msgid "File Not Found" msgstr "未找到文件" @@ -440,7 +449,8 @@ msgstr "修改" msgid "Modify Config" msgstr "修改配置文件" -#: src/views/domain/DomainEdit.vue:36 src/views/domain/DomainList.vue:15 +#: src/views/config/config.ts:9 src/views/domain/DomainEdit.vue:36 +#: src/views/domain/DomainList.vue:15 msgid "Name" msgstr "名称" @@ -717,7 +727,12 @@ msgstr "用户名或密码错误" msgid "Theme" msgstr "主题" -#: src/views/domain/DomainList.vue:41 src/views/user/User.vue:37 +#: src/language/constants.ts:23 src/views/config/config.ts:14 +msgid "Type" +msgstr "类型" + +#: src/views/config/config.ts:29 src/views/domain/DomainList.vue:41 +#: src/views/user/User.vue:37 msgid "Updated at" msgstr "修改时间" diff --git a/frontend/src/language/zh_TW/app.po b/frontend/src/language/zh_TW/app.po index d408649fa..71d3995bd 100644 --- a/frontend/src/language/zh_TW/app.po +++ b/frontend/src/language/zh_TW/app.po @@ -21,7 +21,8 @@ msgstr "關於" msgid "Access Logs" msgstr "訪問日誌" -#: src/views/domain/DomainList.vue:47 src/views/user/User.vue:43 +#: src/views/config/config.ts:36 src/views/domain/DomainList.vue:47 +#: src/views/user/User.vue:43 msgid "Action" msgstr "操作" @@ -205,6 +206,10 @@ msgstr "刪除站點:%{site_name}" msgid "Development Mode" msgstr "開發模式" +#: src/views/config/config.ts:20 +msgid "Dir" +msgstr "" + #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:20 msgid "Directive" msgstr "指令" @@ -308,6 +313,10 @@ msgstr "啟用失敗 %{msg}" msgid "Failed to get certificate information" msgstr "獲取證書信息失敗" +#: src/views/config/config.ts:22 +msgid "File" +msgstr "" + #: src/views/other/Error.vue:3 src/views/other/Error.vue:4 msgid "File Not Found" msgstr "未找到檔案" @@ -443,7 +452,8 @@ msgstr "修改" msgid "Modify Config" msgstr "修改配置" -#: src/views/domain/DomainEdit.vue:36 src/views/domain/DomainList.vue:15 +#: src/views/config/config.ts:9 src/views/domain/DomainEdit.vue:36 +#: src/views/domain/DomainList.vue:15 msgid "Name" msgstr "名稱" @@ -724,7 +734,12 @@ msgstr "用戶名或密碼不正確" msgid "Theme" msgstr "外觀樣式" -#: src/views/domain/DomainList.vue:41 src/views/user/User.vue:37 +#: src/language/constants.ts:23 src/views/config/config.ts:14 +msgid "Type" +msgstr "" + +#: src/views/config/config.ts:29 src/views/domain/DomainList.vue:41 +#: src/views/user/User.vue:37 msgid "Updated at" msgstr "修改時間" diff --git a/frontend/src/routes/index.ts b/frontend/src/routes/index.ts index 2c843213f..54d0d39bd 100644 --- a/frontend/src/routes/index.ts +++ b/frontend/src/routes/index.ts @@ -10,7 +10,8 @@ import { InfoCircleOutlined, UserOutlined, FileTextOutlined, - SettingOutlined + SettingOutlined, + SafetyCertificateOutlined } from '@ant-design/icons-vue' const {$gettext} = gettext @@ -91,6 +92,14 @@ export const routes = [ hiddenInSidebar: true } }, + { + path: 'cert', + name: () => $gettext('Certification'), + component: () => import('@/views/cert/Cert.vue'), + meta: { + icon: SafetyCertificateOutlined + } + }, { path: 'terminal', name: () => $gettext('Terminal'), diff --git a/frontend/src/version.json b/frontend/src/version.json index 75a1ec37d..fd5fa9ae0 100644 --- a/frontend/src/version.json +++ b/frontend/src/version.json @@ -1 +1 @@ -{"version":"1.7.0","build_id":62,"total_build":132} \ No newline at end of file +{"version":"1.7.0","build_id":63,"total_build":133} \ No newline at end of file diff --git a/frontend/src/views/cert/Cert.vue b/frontend/src/views/cert/Cert.vue new file mode 100644 index 000000000..7cd2cbece --- /dev/null +++ b/frontend/src/views/cert/Cert.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/frontend/src/views/config/config.tsx b/frontend/src/views/config/config.ts similarity index 96% rename from frontend/src/views/config/config.tsx rename to frontend/src/views/config/config.ts index 662a77e79..63a1bc18c 100644 --- a/frontend/src/views/config/config.tsx +++ b/frontend/src/views/config/config.ts @@ -3,7 +3,6 @@ import gettext from '@/gettext' const {$gettext} = gettext -import {Badge} from 'ant-design-vue' import {h} from 'vue' const configColumns = [{ diff --git a/frontend/src/views/template/Template.vue b/frontend/src/views/template/Template.vue new file mode 100644 index 000000000..0f413ca33 --- /dev/null +++ b/frontend/src/views/template/Template.vue @@ -0,0 +1,11 @@ + + + + + diff --git a/frontend/version.json b/frontend/version.json index 75a1ec37d..fd5fa9ae0 100644 --- a/frontend/version.json +++ b/frontend/version.json @@ -1 +1 @@ -{"version":"1.7.0","build_id":62,"total_build":132} \ No newline at end of file +{"version":"1.7.0","build_id":63,"total_build":133} \ No newline at end of file diff --git a/server/api/cert.go b/server/api/cert.go index 58a59d497..38bd43a50 100644 --- a/server/api/cert.go +++ b/server/api/cert.go @@ -6,6 +6,7 @@ import ( "github.com/0xJacky/Nginx-UI/server/pkg/nginx" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" + "github.com/spf13/cast" "log" "net/http" "strings" @@ -117,7 +118,8 @@ func IssueCert(c *gin.Context) { } err = certModel.Updates(&model.Cert{ - SSLCertificatePath: sslCertificatePath, + SSLCertificatePath: sslCertificatePath, + SSLCertificateKeyPath: sslCertificateKeyPath, }) if err != nil { @@ -137,3 +139,108 @@ func IssueCert(c *gin.Context) { } } + +func GetCertList(c *gin.Context) { + certList := model.GetCertList(c.Query("name"), c.Query("domain")) + + c.JSON(http.StatusOK, gin.H{ + "data": certList, + }) +} + +func GetCert(c *gin.Context) { + certModel, err := model.FirstCertByID(cast.ToInt(c.Param("id"))) + + if err != nil { + ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, certModel) +} + +func AddCert(c *gin.Context) { + var json struct { + Name string `json:"name" binding:"required"` + Domain string `json:"domain" binding:"required"` + SSLCertificatePath string `json:"ssl_certificate_path" binding:"required"` + SSLCertificateKeyPath string `json:"ssl_certificate_key_path" binding:"required"` + } + if !BindAndValid(c, &json) { + return + } + certModel, err := model.FirstOrCreateCert(json.Domain) + + if err != nil { + ErrHandler(c, err) + return + } + + err = certModel.Updates(&model.Cert{ + Name: json.Name, + Domain: json.Domain, + SSLCertificatePath: json.SSLCertificatePath, + SSLCertificateKeyPath: json.SSLCertificateKeyPath, + }) + + if err != nil { + ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, nil) +} + +func ModifyCert(c *gin.Context) { + id := cast.ToInt(c.Param("id")) + certModel, err := model.FirstCertByID(id) + + var json struct { + Name string `json:"name" binding:"required"` + Domain string `json:"domain" binding:"required"` + SSLCertificatePath string `json:"ssl_certificate_path" binding:"required"` + SSLCertificateKeyPath string `json:"ssl_certificate_key_path" binding:"required"` + } + + if !BindAndValid(c, &json) { + return + } + + if err != nil { + ErrHandler(c, err) + return + } + + err = certModel.Updates(&model.Cert{ + Name: json.Name, + Domain: json.Domain, + SSLCertificatePath: json.SSLCertificatePath, + SSLCertificateKeyPath: json.SSLCertificateKeyPath, + }) + + if err != nil { + ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, certModel) +} + +func RemoveCert(c *gin.Context) { + id := cast.ToInt(c.Param("id")) + certModel, err := model.FirstCertByID(id) + + if err != nil { + ErrHandler(c, err) + return + } + + err = certModel.Remove() + + if err != nil { + ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, nil) +} diff --git a/server/api/domain.go b/server/api/domain.go index 00d5161cc..211d2061d 100644 --- a/server/api/domain.go +++ b/server/api/domain.go @@ -1,365 +1,381 @@ package api import ( - "github.com/0xJacky/Nginx-UI/server/model" - "github.com/0xJacky/Nginx-UI/server/pkg/cert" - "github.com/0xJacky/Nginx-UI/server/pkg/config_list" - "github.com/0xJacky/Nginx-UI/server/pkg/nginx" - "github.com/gin-gonic/gin" - "log" - "net/http" - "os" - "path/filepath" - "strings" - "time" + "github.com/0xJacky/Nginx-UI/server/model" + "github.com/0xJacky/Nginx-UI/server/pkg/cert" + "github.com/0xJacky/Nginx-UI/server/pkg/config_list" + "github.com/0xJacky/Nginx-UI/server/pkg/nginx" + "github.com/gin-gonic/gin" + "log" + "net/http" + "os" + "path/filepath" + "strings" + "time" ) func GetDomains(c *gin.Context) { - name := c.Query("name") - orderBy := c.Query("order_by") - sort := c.DefaultQuery("sort", "desc") - - mySort := map[string]string{ - "enabled": "bool", - "name": "string", - "modify": "time", - } - - configFiles, err := os.ReadDir(nginx.GetNginxConfPath("sites-available")) - - if err != nil { - ErrHandler(c, err) - return - } - - enabledConfig, err := os.ReadDir(filepath.Join(nginx.GetNginxConfPath("sites-enabled"))) - - if err != nil { - ErrHandler(c, err) - return - } - - enabledConfigMap := make(map[string]bool) - for i := range enabledConfig { - enabledConfigMap[enabledConfig[i].Name()] = true - } - - var configs []gin.H - - for i := range configFiles { - file := configFiles[i] - fileInfo, _ := file.Info() - if !file.IsDir() { - if name != "" && !strings.Contains(file.Name(), name) { - continue - } - configs = append(configs, gin.H{ - "name": file.Name(), - "size": fileInfo.Size(), - "modify": fileInfo.ModTime(), - "enabled": enabledConfigMap[file.Name()], - }) - } - } - - configs = config_list.Sort(orderBy, sort, mySort[orderBy], configs) - - c.JSON(http.StatusOK, gin.H{ - "data": configs, - }) + name := c.Query("name") + orderBy := c.Query("order_by") + sort := c.DefaultQuery("sort", "desc") + + mySort := map[string]string{ + "enabled": "bool", + "name": "string", + "modify": "time", + } + + configFiles, err := os.ReadDir(nginx.GetNginxConfPath("sites-available")) + + if err != nil { + ErrHandler(c, err) + return + } + + enabledConfig, err := os.ReadDir(filepath.Join(nginx.GetNginxConfPath("sites-enabled"))) + + if err != nil { + ErrHandler(c, err) + return + } + + enabledConfigMap := make(map[string]bool) + for i := range enabledConfig { + enabledConfigMap[enabledConfig[i].Name()] = true + } + + var configs []gin.H + + for i := range configFiles { + file := configFiles[i] + fileInfo, _ := file.Info() + if !file.IsDir() { + if name != "" && !strings.Contains(file.Name(), name) { + continue + } + configs = append(configs, gin.H{ + "name": file.Name(), + "size": fileInfo.Size(), + "modify": fileInfo.ModTime(), + "enabled": enabledConfigMap[file.Name()], + }) + } + } + + configs = config_list.Sort(orderBy, sort, mySort[orderBy], configs) + + c.JSON(http.StatusOK, gin.H{ + "data": configs, + }) } type CertificateInfo struct { - SubjectName string `json:"subject_name"` - IssuerName string `json:"issuer_name"` - NotAfter time.Time `json:"not_after"` - NotBefore time.Time `json:"not_before"` + SubjectName string `json:"subject_name"` + IssuerName string `json:"issuer_name"` + NotAfter time.Time `json:"not_after"` + NotBefore time.Time `json:"not_before"` } func GetDomain(c *gin.Context) { - rewriteName, ok := c.Get("rewriteConfigFileName") + rewriteName, ok := c.Get("rewriteConfigFileName") - name := c.Param("name") + name := c.Param("name") - // for modify filename - if ok { - name = rewriteName.(string) - } + // for modify filename + if ok { + name = rewriteName.(string) + } - path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) + path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) - enabled := true - if _, err := os.Stat(filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name)); os.IsNotExist(err) { - enabled = false - } + enabled := true + if _, err := os.Stat(filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name)); os.IsNotExist(err) { + enabled = false + } - config, err := nginx.ParseNgxConfig(path) + config, err := nginx.ParseNgxConfig(path) - if err != nil { - ErrHandler(c, err) - return - } + if err != nil { + ErrHandler(c, err) + return + } - certInfoMap := make(map[int]CertificateInfo) - var serverName string - for serverIdx, server := range config.Servers { - for _, directive := range server.Directives { + certInfoMap := make(map[int]CertificateInfo) + var serverName string + for serverIdx, server := range config.Servers { + for _, directive := range server.Directives { - if directive.Directive == "server_name" { - serverName = strings.ReplaceAll(directive.Params, " ", "_") - continue - } + if directive.Directive == "server_name" { + serverName = strings.ReplaceAll(directive.Params, " ", "_") + continue + } - if directive.Directive == "ssl_certificate" { + if directive.Directive == "ssl_certificate" { - pubKey, err := cert.GetCertInfo(directive.Params) + pubKey, err := cert.GetCertInfo(directive.Params) - if err != nil { - log.Println("Failed to get certificate information", err) - break - } + if err != nil { + log.Println("Failed to get certificate information", err) + break + } - certInfoMap[serverIdx] = CertificateInfo{ - SubjectName: pubKey.Subject.CommonName, - IssuerName: pubKey.Issuer.CommonName, - NotAfter: pubKey.NotAfter, - NotBefore: pubKey.NotBefore, - } + certInfoMap[serverIdx] = CertificateInfo{ + SubjectName: pubKey.Subject.CommonName, + IssuerName: pubKey.Issuer.CommonName, + NotAfter: pubKey.NotAfter, + NotBefore: pubKey.NotBefore, + } - break - } - } - } + break + } + } + } - _, err = model.FirstCert(serverName) + certModel, _ := model.FirstCert(serverName) - c.JSON(http.StatusOK, gin.H{ - "enabled": enabled, - "name": name, - "config": config.BuildConfig(), - "tokenized": config, - "auto_cert": err == nil, - "cert_info": certInfoMap, - }) + c.JSON(http.StatusOK, gin.H{ + "enabled": enabled, + "name": name, + "config": config.BuildConfig(), + "tokenized": config, + "auto_cert": certModel.AutoCert == model.AutoCertEnabled, + "cert_info": certInfoMap, + }) } func EditDomain(c *gin.Context) { - name := c.Param("name") - - if name == "" { - c.JSON(http.StatusNotAcceptable, gin.H{ - "message": "param name is empty", - }) - return - } - - var json struct { - Name string `json:"name" binding:"required"` - Content string `json:"content"` - } - - if !BindAndValid(c, &json) { - return - } - - path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) - - err := os.WriteFile(path, []byte(json.Content), 0644) - if err != nil { - ErrHandler(c, err) - return - } - enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name) - // rename the config file if needed - if name != json.Name { - newPath := filepath.Join(nginx.GetNginxConfPath("sites-available"), json.Name) - // recreate soft link - log.Println(enabledConfigFilePath) - if _, err = os.Stat(enabledConfigFilePath); err == nil { - log.Println(enabledConfigFilePath) - _ = os.Remove(enabledConfigFilePath) - enabledConfigFilePath = filepath.Join(nginx.GetNginxConfPath("sites-enabled"), json.Name) - err = os.Symlink(newPath, enabledConfigFilePath) - - if err != nil { - ErrHandler(c, err) - return - } - } - err = os.Rename(path, newPath) - if err != nil { - ErrHandler(c, err) - return - } - name = json.Name - c.Set("rewriteConfigFileName", name) - - } - - enabledConfigFilePath = filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name) - if _, err = os.Stat(enabledConfigFilePath); err == nil { - // Test nginx configuration - err = nginx.TestNginxConf() - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": err.Error(), - }) - return - } - - output := nginx.ReloadNginx() - - if output != "" && strings.Contains(output, "error") { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": output, - }) - return - } - } - - GetDomain(c) + name := c.Param("name") + + if name == "" { + c.JSON(http.StatusNotAcceptable, gin.H{ + "message": "param name is empty", + }) + return + } + + var json struct { + Name string `json:"name" binding:"required"` + Content string `json:"content"` + } + + if !BindAndValid(c, &json) { + return + } + + path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) + + err := os.WriteFile(path, []byte(json.Content), 0644) + if err != nil { + ErrHandler(c, err) + return + } + enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name) + // rename the config file if needed + if name != json.Name { + newPath := filepath.Join(nginx.GetNginxConfPath("sites-available"), json.Name) + // recreate soft link + log.Println(enabledConfigFilePath) + if _, err = os.Stat(enabledConfigFilePath); err == nil { + log.Println(enabledConfigFilePath) + _ = os.Remove(enabledConfigFilePath) + enabledConfigFilePath = filepath.Join(nginx.GetNginxConfPath("sites-enabled"), json.Name) + err = os.Symlink(newPath, enabledConfigFilePath) + + if err != nil { + ErrHandler(c, err) + return + } + } + err = os.Rename(path, newPath) + if err != nil { + ErrHandler(c, err) + return + } + name = json.Name + c.Set("rewriteConfigFileName", name) + + } + + enabledConfigFilePath = filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name) + if _, err = os.Stat(enabledConfigFilePath); err == nil { + // Test nginx configuration + err = nginx.TestNginxConf() + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": err.Error(), + }) + return + } + + output := nginx.ReloadNginx() + + if output != "" && strings.Contains(output, "error") { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": output, + }) + return + } + } + + GetDomain(c) } func EnableDomain(c *gin.Context) { - configFilePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), c.Param("name")) - enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name")) - - _, err := os.Stat(configFilePath) - - if err != nil { - ErrHandler(c, err) - return - } - - if _, err = os.Stat(enabledConfigFilePath); os.IsNotExist(err) { - err = os.Symlink(configFilePath, enabledConfigFilePath) - - if err != nil { - ErrHandler(c, err) - return - } - } - - // Test nginx config, if not pass then rollback. - err = nginx.TestNginxConf() - if err != nil { - _ = os.Remove(enabledConfigFilePath) - c.JSON(http.StatusInternalServerError, gin.H{ - "message": err.Error(), - }) - return - } - - output := nginx.ReloadNginx() - - if output != "" && strings.Contains(output, "error") { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": output, - }) - return - } - - c.JSON(http.StatusOK, gin.H{ - "message": "ok", - }) + configFilePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), c.Param("name")) + enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name")) + + _, err := os.Stat(configFilePath) + + if err != nil { + ErrHandler(c, err) + return + } + + if _, err = os.Stat(enabledConfigFilePath); os.IsNotExist(err) { + err = os.Symlink(configFilePath, enabledConfigFilePath) + + if err != nil { + ErrHandler(c, err) + return + } + } + + // Test nginx config, if not pass then rollback. + err = nginx.TestNginxConf() + if err != nil { + _ = os.Remove(enabledConfigFilePath) + c.JSON(http.StatusInternalServerError, gin.H{ + "message": err.Error(), + }) + return + } + + output := nginx.ReloadNginx() + + if output != "" && strings.Contains(output, "error") { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": output, + }) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) } func DisableDomain(c *gin.Context) { - enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name")) - - _, err := os.Stat(enabledConfigFilePath) - - if err != nil { - ErrHandler(c, err) - return - } - - err = os.Remove(enabledConfigFilePath) - - if err != nil { - ErrHandler(c, err) - return - } - - // delete auto cert record - certModel := model.Cert{Domain: c.Param("name")} - err = certModel.Remove() - if err != nil { - ErrHandler(c, err) - return - } - - output := nginx.ReloadNginx() - - if output != "" { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": output, - }) - return - } - - c.JSON(http.StatusOK, gin.H{ - "message": "ok", - }) + enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name")) + + _, err := os.Stat(enabledConfigFilePath) + + if err != nil { + ErrHandler(c, err) + return + } + + err = os.Remove(enabledConfigFilePath) + + if err != nil { + ErrHandler(c, err) + return + } + + // delete auto cert record + certModel := model.Cert{Domain: c.Param("name")} + err = certModel.Remove() + if err != nil { + ErrHandler(c, err) + return + } + + output := nginx.ReloadNginx() + + if output != "" { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": output, + }) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) } func DeleteDomain(c *gin.Context) { - var err error - name := c.Param("name") - availablePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) - enabledPath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name) - - if _, err = os.Stat(availablePath); os.IsNotExist(err) { - c.JSON(http.StatusNotFound, gin.H{ - "message": "site not found", - }) - return - } - - if _, err = os.Stat(enabledPath); err == nil { - c.JSON(http.StatusNotAcceptable, gin.H{ - "message": "site is enabled", - }) - return - } - - certModel := model.Cert{Domain: name} - _ = certModel.Remove() - - err = os.Remove(availablePath) - - if err != nil { - ErrHandler(c, err) - return - } - - c.JSON(http.StatusOK, gin.H{ - "message": "ok", - }) + var err error + name := c.Param("name") + availablePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) + enabledPath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name) + + if _, err = os.Stat(availablePath); os.IsNotExist(err) { + c.JSON(http.StatusNotFound, gin.H{ + "message": "site not found", + }) + return + } + + if _, err = os.Stat(enabledPath); err == nil { + c.JSON(http.StatusNotAcceptable, gin.H{ + "message": "site is enabled", + }) + return + } + + certModel := model.Cert{Domain: name} + _ = certModel.Remove() + + err = os.Remove(availablePath) + + if err != nil { + ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) } func AddDomainToAutoCert(c *gin.Context) { - domain := c.Param("domain") - - certModel, err := model.FirstOrCreateCert(domain) - if err != nil { - ErrHandler(c, err) - return - } - c.JSON(http.StatusOK, certModel) + domain := c.Param("domain") + domain = strings.ReplaceAll(domain, " ", "_") + certModel, err := model.FirstOrCreateCert(domain) + + if err != nil { + ErrHandler(c, err) + return + } + + err = certModel.Updates(&model.Cert{ + AutoCert: model.AutoCertEnabled, + }) + + if err != nil { + ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, certModel) } func RemoveDomainFromAutoCert(c *gin.Context) { - certModel := model.Cert{ - Domain: c.Param("domain"), - } - err := certModel.Remove() - - if err != nil { - ErrHandler(c, err) - return - } - c.JSON(http.StatusOK, nil) + domain := c.Param("domain") + domain = strings.ReplaceAll(domain, " ", "_") + certModel := model.Cert{ + Domain: domain, + } + + err := certModel.Updates(&model.Cert{ + AutoCert: model.AutoCertDisabled, + }) + + if err != nil { + ErrHandler(c, err) + return + } + c.JSON(http.StatusOK, nil) } diff --git a/server/model/cert.go b/server/model/cert.go index efabea4f2..86f49e3d7 100644 --- a/server/model/cert.go +++ b/server/model/cert.go @@ -6,10 +6,18 @@ import ( "path/filepath" ) +const ( + AutoCertEnabled = 1 + AutoCertDisabled = -1 +) + type Cert struct { Model - Domain string `json:"domain"` - SSLCertificatePath string `json:"ssl_certificate_path"` + Name string `json:"name"` + Domain string `json:"domain"` + SSLCertificatePath string `json:"ssl_certificate_path"` + SSLCertificateKeyPath string `json:"ssl_certificate_key_path"` + AutoCert int `json:"auto_cert"` } func FirstCert(domain string) (c Cert, err error) { @@ -27,7 +35,7 @@ func FirstOrCreateCert(domain string) (c Cert, err error) { func GetAutoCertList() (c []Cert) { var t []Cert - db.Find(&t) + db.Where("auto_cert", AutoCertEnabled).Find(&t) // check if this domain is enabled enabledConfig, err := os.ReadDir(filepath.Join(nginx.GetNginxConfPath("sites-enabled"))) @@ -50,6 +58,24 @@ func GetAutoCertList() (c []Cert) { return } +func GetCertList(name, domain string) (c []Cert) { + tx := db + if name != "" { + tx = tx.Where("name LIKE ? or domain LIKE ?", "%"+name+"%", "%"+name+"%") + } + if domain != "" { + tx = tx.Where("domain LIKE ?", "%"+domain+"%") + } + tx.Find(&c) + return +} + +func FirstCertByID(id int) (c Cert, err error) { + err = db.First(&c, id).Error + + return +} + func (c *Cert) Updates(n *Cert) error { return db.Model(c).Updates(n).Error } diff --git a/server/router/routers.go b/server/router/routers.go index b60173505..e782a1067 100644 --- a/server/router/routers.go +++ b/server/router/routers.go @@ -77,10 +77,15 @@ func InitRouter() *gin.Engine { g.GET("cert/issue", api.IssueCert) + g.GET("certs", api.GetCertList) + g.GET("cert/:id", api.GetCert) + g.POST("cert", api.AddCert) + g.POST("cert/:id", api.ModifyCert) + g.DELETE("cert/:id", api.RemoveCert) // Add domain to auto-renew cert list - g.POST("cert/:domain", api.AddDomainToAutoCert) + g.POST("auto_cert/:domain", api.AddDomainToAutoCert) // Delete domain from auto-renew cert list - g.DELETE("cert/:domain", api.RemoveDomainFromAutoCert) + g.DELETE("auto_cert/:domain", api.RemoveDomainFromAutoCert) // pty g.GET("pty", api.Pty) From 8a9d59cd03673f30788c0483427f5aa20126d645 Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Tue, 3 Jan 2023 00:30:26 +0800 Subject: [PATCH 12/22] chore: update translate --- frontend/src/language/en/app.po | 92 ++++++++++++++--------- frontend/src/language/messages.pot | 69 ++++++++++++------ frontend/src/language/translations.json | 2 +- frontend/src/language/zh_CN/app.mo | Bin 10027 -> 10289 bytes frontend/src/language/zh_CN/app.po | 89 ++++++++++++++--------- frontend/src/language/zh_TW/app.po | 93 +++++++++++++++--------- 6 files changed, 220 insertions(+), 125 deletions(-) diff --git a/frontend/src/language/en/app.po b/frontend/src/language/en/app.po index be5d523ee..4e0ad27f9 100644 --- a/frontend/src/language/en/app.po +++ b/frontend/src/language/en/app.po @@ -9,16 +9,16 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: src/routes/index.ts:135 +#: src/routes/index.ts:144 msgid "About" msgstr "About" -#: src/routes/index.ts:110 src/views/domain/ngx_conf/LogEntry.vue:64 +#: src/routes/index.ts:119 src/views/domain/ngx_conf/LogEntry.vue:64 msgid "Access Logs" msgstr "" -#: src/views/config/config.ts:36 src/views/domain/DomainList.vue:47 -#: src/views/user/User.vue:43 +#: src/views/cert/Cert.vue:75 src/views/config/config.ts:36 +#: src/views/domain/DomainList.vue:47 src/views/user/User.vue:43 msgid "Action" msgstr "Action" @@ -40,7 +40,7 @@ msgstr "Add Directive Below" msgid "Add Location" msgstr "Add Location" -#: src/routes/index.ts:56 src/views/domain/DomainAdd.vue:2 +#: src/routes/index.ts:57 src/views/domain/DomainAdd.vue:2 msgid "Add Site" msgstr "Add Site" @@ -68,6 +68,10 @@ msgstr "Are you sure you want to remove this directive?" msgid "Auto" msgstr "" +#: src/views/cert/Cert.vue:38 +msgid "Auto Cert" +msgstr "" + #: src/views/nginx_log/NginxLog.vue:4 msgid "Auto Refresh" msgstr "" @@ -131,6 +135,11 @@ msgstr "Certificate is valid" msgid "Certificate Status" msgstr "Certificate Status" +#: src/routes/index.ts:97 src/views/cert/Cert.vue:2 +#, fuzzy +msgid "Certification" +msgstr "Certificate is valid" + #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:30 #: src/views/domain/ngx_conf/LocationEditor.vue:31 #: src/views/domain/ngx_conf/LocationEditor.vue:47 @@ -181,7 +190,7 @@ msgstr "" msgid "Dark" msgstr "" -#: src/routes/index.ts:28 +#: src/routes/index.ts:29 msgid "Dashboard" msgstr "Dashboard" @@ -223,10 +232,10 @@ msgstr "Directives" msgid "Disable auto-renewal failed for %{name}" msgstr "Disable auto-renewal failed for %{name}" -#: src/views/domain/DomainEdit.vue:10 src/views/domain/DomainEdit.vue:9 -#: src/views/domain/DomainList.vue:16 src/views/domain/DomainList.vue:34 -#: src/views/domain/DomainList.vue:7 src/views/domain/DomainList.vue:8 -#: src/views/domain/DomainList.vue:9 +#: src/views/cert/Cert.vue:48 src/views/domain/DomainEdit.vue:10 +#: src/views/domain/DomainEdit.vue:9 src/views/domain/DomainList.vue:16 +#: src/views/domain/DomainList.vue:34 src/views/domain/DomainList.vue:7 +#: src/views/domain/DomainList.vue:8 src/views/domain/DomainList.vue:9 msgid "Disabled" msgstr "Disabled" @@ -238,6 +247,10 @@ msgstr "Disabled successfully" msgid "Disk IO" msgstr "Disk IO" +#: src/views/cert/Cert.vue:29 +msgid "Domain" +msgstr "" + #: src/views/domain/DomainAdd.vue:60 msgid "Domain Config Created Successfully" msgstr "Domain Config Created Successfully" @@ -246,11 +259,11 @@ msgstr "Domain Config Created Successfully" msgid "Edit %{n}" msgstr "Edit %{n}" -#: src/routes/index.ts:88 src/views/config/ConfigEdit.vue:2 +#: src/routes/index.ts:89 src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "Edit Configuration" -#: src/routes/index.ts:60 +#: src/routes/index.ts:61 msgid "Edit Site" msgstr "Edit Site" @@ -270,10 +283,11 @@ msgstr "Enable failed" msgid "Enable TLS" msgstr "Enable TLS" -#: src/views/domain/DomainEdit.vue:33 src/views/domain/DomainEdit.vue:6 -#: src/views/domain/DomainEdit.vue:7 src/views/domain/DomainList.vue:10 -#: src/views/domain/DomainList.vue:11 src/views/domain/DomainList.vue:12 -#: src/views/domain/DomainList.vue:19 src/views/domain/DomainList.vue:31 +#: src/views/cert/Cert.vue:45 src/views/domain/DomainEdit.vue:33 +#: src/views/domain/DomainEdit.vue:6 src/views/domain/DomainEdit.vue:7 +#: src/views/domain/DomainList.vue:10 src/views/domain/DomainList.vue:11 +#: src/views/domain/DomainList.vue:12 src/views/domain/DomainList.vue:19 +#: src/views/domain/DomainList.vue:31 msgid "Enabled" msgstr "Enabled" @@ -286,7 +300,7 @@ msgstr "Enabled successfully" msgid "Encrypt website with Let's Encrypt" msgstr "Encrypt website with Let's Encrypt" -#: src/routes/index.ts:114 src/views/domain/ngx_conf/LogEntry.vue:68 +#: src/routes/index.ts:123 src/views/domain/ngx_conf/LogEntry.vue:68 msgid "Error Logs" msgstr "" @@ -342,7 +356,7 @@ msgstr "" msgid "Getting the certificate, please wait..." msgstr "Getting the certificate, please wait..." -#: src/routes/index.ts:21 +#: src/routes/index.ts:22 msgid "Home" msgstr "Home" @@ -354,7 +368,7 @@ msgstr "" msgid "HTTP Port" msgstr "" -#: src/routes/index.ts:145 src/views/other/Install.vue:128 +#: src/routes/index.ts:154 src/views/other/Install.vue:128 msgid "Install" msgstr "Install" @@ -399,7 +413,7 @@ msgstr "Location" msgid "Locations" msgstr "Locations" -#: src/routes/index.ts:151 src/views/other/Login.vue:103 +#: src/routes/index.ts:160 src/views/other/Login.vue:103 msgid "Login" msgstr "Login" @@ -419,15 +433,15 @@ msgstr "" "Make sure you have configured a reverse proxy for .well-known directory to " "HTTPChallengePort (default: 9180) before getting the certificate." -#: src/routes/index.ts:69 src/routes/index.ts:78 +#: src/routes/index.ts:70 src/routes/index.ts:79 msgid "Manage Configs" msgstr "Manage Configs" -#: src/routes/index.ts:44 src/views/domain/DomainList.vue:2 +#: src/routes/index.ts:45 src/views/domain/DomainList.vue:2 msgid "Manage Sites" msgstr "Manage Sites" -#: src/routes/index.ts:36 src/views/user/User.vue:2 +#: src/routes/index.ts:37 src/views/user/User.vue:2 msgid "Manage Users" msgstr "Manage Users" @@ -453,8 +467,8 @@ msgstr "Modify Config" msgid "Modify Config" msgstr "Modify Config" -#: src/views/config/config.ts:9 src/views/domain/DomainEdit.vue:36 -#: src/views/domain/DomainList.vue:15 +#: src/views/cert/Cert.vue:13 src/views/config/config.ts:9 +#: src/views/domain/DomainEdit.vue:36 src/views/domain/DomainList.vue:15 msgid "Name" msgstr "Name" @@ -486,7 +500,7 @@ msgstr "" msgid "Nginx Error Log Path" msgstr "" -#: src/routes/index.ts:104 src/views/nginx_log/NginxLog.vue:2 +#: src/routes/index.ts:113 src/views/nginx_log/NginxLog.vue:2 msgid "Nginx Log" msgstr "" @@ -497,7 +511,7 @@ msgstr "" msgid "No" msgstr "No" -#: src/routes/index.ts:157 src/routes/index.ts:159 +#: src/routes/index.ts:166 src/routes/index.ts:168 msgid "Not Found" msgstr "Not Found" @@ -559,7 +573,7 @@ msgstr "Please input your password!" msgid "Please input your username!" msgstr "Please input your username!" -#: src/routes/index.ts:127 src/views/preference/Preference.vue:2 +#: src/routes/index.ts:136 src/views/preference/Preference.vue:2 msgid "Preference" msgstr "" @@ -682,15 +696,25 @@ msgstr "server_name parameter is required" msgid "Single Directive" msgstr "Single Directive" -#: src/routes/index.ts:118 +#: src/routes/index.ts:127 #, fuzzy msgid "Site Logs" msgstr "Sites List" -#: src/routes/index.ts:52 +#: src/routes/index.ts:53 msgid "Sites List" msgstr "Sites List" +#: src/views/cert/Cert.vue:62 +#, fuzzy +msgid "SSL Certificate Key Path" +msgstr "Certificate Status" + +#: src/views/cert/Cert.vue:55 +#, fuzzy +msgid "SSL Certificate Path" +msgstr "Certificate Status" + #: src/views/domain/DomainList.vue:24 msgid "Status" msgstr "Status" @@ -712,7 +736,7 @@ msgstr "Swap" msgid "Table" msgstr "Enabled" -#: src/routes/index.ts:96 src/views/pty/Terminal.vue:2 +#: src/routes/index.ts:105 src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "Terminal" @@ -740,12 +764,12 @@ msgstr "" msgid "Theme" msgstr "" -#: src/language/constants.ts:23 src/views/config/config.ts:14 +#: src/views/config/config.ts:14 msgid "Type" msgstr "" -#: src/views/config/config.ts:29 src/views/domain/DomainList.vue:41 -#: src/views/user/User.vue:37 +#: src/views/cert/Cert.vue:69 src/views/config/config.ts:29 +#: src/views/domain/DomainList.vue:41 src/views/user/User.vue:37 msgid "Updated at" msgstr "Updated at" diff --git a/frontend/src/language/messages.pot b/frontend/src/language/messages.pot index 847ab7823..d4be31a0e 100644 --- a/frontend/src/language/messages.pot +++ b/frontend/src/language/messages.pot @@ -2,15 +2,16 @@ msgid "" msgstr "" "Content-Type: text/plain; charset=UTF-8\n" -#: src/routes/index.ts:135 +#: src/routes/index.ts:144 msgid "About" msgstr "" -#: src/routes/index.ts:110 +#: src/routes/index.ts:119 #: src/views/domain/ngx_conf/LogEntry.vue:64 msgid "Access Logs" msgstr "" +#: src/views/cert/Cert.vue:75 #: src/views/config/config.ts:36 #: src/views/domain/DomainList.vue:47 #: src/views/user/User.vue:43 @@ -35,7 +36,7 @@ msgstr "" msgid "Add Location" msgstr "" -#: src/routes/index.ts:56 +#: src/routes/index.ts:57 #: src/views/domain/DomainAdd.vue:2 msgid "Add Site" msgstr "" @@ -63,6 +64,10 @@ msgstr "" msgid "Auto" msgstr "" +#: src/views/cert/Cert.vue:38 +msgid "Auto Cert" +msgstr "" + #: src/views/nginx_log/NginxLog.vue:4 msgid "Auto Refresh" msgstr "" @@ -128,6 +133,11 @@ msgstr "" msgid "Certificate Status" msgstr "" +#: src/routes/index.ts:97 +#: src/views/cert/Cert.vue:2 +msgid "Certification" +msgstr "" + #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:30 #: src/views/domain/ngx_conf/LocationEditor.vue:31 #: src/views/domain/ngx_conf/LocationEditor.vue:47 @@ -178,7 +188,7 @@ msgstr "" msgid "Dark" msgstr "" -#: src/routes/index.ts:28 +#: src/routes/index.ts:29 msgid "Dashboard" msgstr "" @@ -221,6 +231,7 @@ msgstr "" msgid "Disable auto-renewal failed for %{name}" msgstr "" +#: src/views/cert/Cert.vue:48 #: src/views/domain/DomainEdit.vue:10 #: src/views/domain/DomainEdit.vue:9 #: src/views/domain/DomainList.vue:16 @@ -240,6 +251,10 @@ msgstr "" msgid "Disk IO" msgstr "" +#: src/views/cert/Cert.vue:29 +msgid "Domain" +msgstr "" + #: src/views/domain/DomainAdd.vue:60 msgid "Domain Config Created Successfully" msgstr "" @@ -249,12 +264,12 @@ msgstr "" msgid "Edit %{n}" msgstr "" -#: src/routes/index.ts:88 +#: src/routes/index.ts:89 #: src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "" -#: src/routes/index.ts:60 +#: src/routes/index.ts:61 msgid "Edit Site" msgstr "" @@ -274,6 +289,7 @@ msgstr "" msgid "Enable TLS" msgstr "" +#: src/views/cert/Cert.vue:45 #: src/views/domain/DomainEdit.vue:33 #: src/views/domain/DomainEdit.vue:6 #: src/views/domain/DomainEdit.vue:7 @@ -295,7 +311,7 @@ msgstr "" msgid "Encrypt website with Let's Encrypt" msgstr "" -#: src/routes/index.ts:114 +#: src/routes/index.ts:123 #: src/views/domain/ngx_conf/LogEntry.vue:68 msgid "Error Logs" msgstr "" @@ -356,7 +372,7 @@ msgstr "" msgid "Getting the certificate, please wait..." msgstr "" -#: src/routes/index.ts:21 +#: src/routes/index.ts:22 msgid "Home" msgstr "" @@ -368,7 +384,7 @@ msgstr "" msgid "HTTP Port" msgstr "" -#: src/routes/index.ts:145 +#: src/routes/index.ts:154 #: src/views/other/Install.vue:128 msgid "Install" msgstr "" @@ -412,7 +428,7 @@ msgstr "" msgid "Locations" msgstr "" -#: src/routes/index.ts:151 +#: src/routes/index.ts:160 #: src/views/other/Login.vue:103 msgid "Login" msgstr "" @@ -429,17 +445,17 @@ msgstr "" msgid "Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate." msgstr "" -#: src/routes/index.ts:69 -#: src/routes/index.ts:78 +#: src/routes/index.ts:70 +#: src/routes/index.ts:79 msgid "Manage Configs" msgstr "" -#: src/routes/index.ts:44 +#: src/routes/index.ts:45 #: src/views/domain/DomainList.vue:2 msgid "Manage Sites" msgstr "" -#: src/routes/index.ts:36 +#: src/routes/index.ts:37 #: src/views/user/User.vue:2 msgid "Manage Users" msgstr "" @@ -465,6 +481,7 @@ msgstr "" msgid "Modify Config" msgstr "" +#: src/views/cert/Cert.vue:13 #: src/views/config/config.ts:9 #: src/views/domain/DomainEdit.vue:36 #: src/views/domain/DomainList.vue:15 @@ -499,7 +516,7 @@ msgstr "" msgid "Nginx Error Log Path" msgstr "" -#: src/routes/index.ts:104 +#: src/routes/index.ts:113 #: src/views/nginx_log/NginxLog.vue:2 msgid "Nginx Log" msgstr "" @@ -511,8 +528,8 @@ msgstr "" msgid "No" msgstr "" -#: src/routes/index.ts:157 -#: src/routes/index.ts:159 +#: src/routes/index.ts:166 +#: src/routes/index.ts:168 msgid "Not Found" msgstr "" @@ -574,7 +591,7 @@ msgstr "" msgid "Please input your username!" msgstr "" -#: src/routes/index.ts:127 +#: src/routes/index.ts:136 #: src/views/preference/Preference.vue:2 msgid "Preference" msgstr "" @@ -704,14 +721,22 @@ msgstr "" msgid "Single Directive" msgstr "" -#: src/routes/index.ts:118 +#: src/routes/index.ts:127 msgid "Site Logs" msgstr "" -#: src/routes/index.ts:52 +#: src/routes/index.ts:53 msgid "Sites List" msgstr "" +#: src/views/cert/Cert.vue:62 +msgid "SSL Certificate Key Path" +msgstr "" + +#: src/views/cert/Cert.vue:55 +msgid "SSL Certificate Path" +msgstr "" + #: src/views/domain/DomainList.vue:24 msgid "Status" msgstr "" @@ -732,7 +757,7 @@ msgstr "" msgid "Table" msgstr "" -#: src/routes/index.ts:96 +#: src/routes/index.ts:105 #: src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "" @@ -757,11 +782,11 @@ msgstr "" msgid "Theme" msgstr "" -#: src/language/constants.ts:23 #: src/views/config/config.ts:14 msgid "Type" msgstr "" +#: src/views/cert/Cert.vue:69 #: src/views/config/config.ts:29 #: src/views/domain/DomainList.vue:41 #: src/views/user/User.vue:37 diff --git a/frontend/src/language/translations.json b/frontend/src/language/translations.json index 7ac418fdf..53f01b49a 100644 --- a/frontend/src/language/translations.json +++ b/frontend/src/language/translations.json @@ -1 +1 @@ -{"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Auto":"自动","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Comments":"注释","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Development Mode":"开发模式","Dir":"目录","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Domain Config Created Successfully":"域名配置文件创建成功","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","File":"文件","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","HTTP Challenge Port":"HTTP Challenge 监听端口","HTTP Port":"HTTP 监听端口","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Jwt Secret":"Jwt 密钥","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","Next":"下一步","Nginx Access Log Path":"Nginx 访问日志路径","Nginx Error Log Path":"Nginx 错误日志路径","Nginx Log":"Nginx 日志","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:当前配置中的 server_name 必须为需要申请证书的域名。","Obtaining certificate":"正在获取证书","OK":"确定","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reloading nginx":"正在重载 Nginx","Reset":"重置","Run Mode":"运行模式","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","Table":"列表","Terminal":"终端","Terminal Start Command":"终端启动命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Type":"类型","Updated at":"修改时间","Updated successfully":"更新成功","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","License":{"Project":"开源许可"}},"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Auto":"自動","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Comments":"註釋","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Development Mode":"開發模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Domain Config Created Successfully":"域名配置文件創建成功","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error Logs":"錯誤日志","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","Next":"下一步","Nginx Log":"Nginx 日誌","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:當前配置中的 server_name 必須為需要申請證書的域名。","Obtaining certificate":"正在獲取證書,請稍等...","OK":"確定","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reloading nginx":"重载 Nginx","Reset":"重設","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","Table":"表格","Terminal":"終端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Updated at":"修改時間","Updated successfully":"已成功更新","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","License":{"Project":"開源軟體授權條款"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"Note: The server_name in the current configuration must be the domain name you need to get the certificate.","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}}} \ No newline at end of file +{"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Auto":"自动","Auto Cert":"自动更新","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Certification":"证书","Comments":"注释","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Development Mode":"开发模式","Dir":"目录","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Domain":"域名","Domain Config Created Successfully":"域名配置文件创建成功","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","File":"文件","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","HTTP Challenge Port":"HTTP Challenge 监听端口","HTTP Port":"HTTP 监听端口","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Jwt Secret":"Jwt 密钥","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","Next":"下一步","Nginx Access Log Path":"Nginx 访问日志路径","Nginx Error Log Path":"Nginx 错误日志路径","Nginx Log":"Nginx 日志","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:当前配置中的 server_name 必须为需要申请证书的域名。","Obtaining certificate":"正在获取证书","OK":"确定","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reloading nginx":"正在重载 Nginx","Reset":"重置","Run Mode":"运行模式","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","SSL Certificate Key Path":"SSL证书密钥路径","SSL Certificate Path":"SSL证书路径","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","Table":"列表","Terminal":"终端","Terminal Start Command":"终端启动命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Type":"类型","Updated at":"修改时间","Updated successfully":"更新成功","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","License":{"Project":"开源许可"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"Note: The server_name in the current configuration must be the domain name you need to get the certificate.","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}},"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Auto":"自動","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Comments":"註釋","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Development Mode":"開發模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Domain Config Created Successfully":"域名配置文件創建成功","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error Logs":"錯誤日志","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","Next":"下一步","Nginx Log":"Nginx 日誌","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:當前配置中的 server_name 必須為需要申請證書的域名。","Obtaining certificate":"正在獲取證書,請稍等...","OK":"確定","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reloading nginx":"重载 Nginx","Reset":"重設","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","Table":"表格","Terminal":"終端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Updated at":"修改時間","Updated successfully":"已成功更新","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","License":{"Project":"開源軟體授權條款"}}} \ No newline at end of file diff --git a/frontend/src/language/zh_CN/app.mo b/frontend/src/language/zh_CN/app.mo index 94ea7ba508ba35a6f01ce7108c5d099ad9d4b0f0..782e3912e57c301d4c1ffd0a3f628a10cf8b8db7 100644 GIT binary patch delta 4001 zcmZA3d2mf<9LDii+(Zz9kl0-!p&CmXs&*<}BAUd$mPW+B1W}E)xnhaENG!GQOKm|i zLl^3g>QFU9jZyt0mX={u%~a`hnwox}oS&Ia&)nyJ-uEo;cFsM?p_Jokfzn#Ob&l;A zX-KvNJNH=Ss(i8iSlu~xxf`fmH!%bsVnzHNBk&o9VU=*_LNN+e_oE+MV_QtYHkgY( z=K}5sh05$Wfx6%;Y>F4qj}MU(U04n8yqd_zHQ=iX#-Xn3X!S%h6?NTk)PP50EgXkY zn1i+H->sogjUD??BQHUncp90MyKKjAVkPR2Z2wc#0DLu_>x$v14*Q}e)DL5E1Zn{D zkxSfCtcROar+-&MK}&fKb>Rh6!&k8dmZAn0!l>$CIBFm}c@*^woQz=oHN$)C;Nz;(yJpY~)leL2VDZSub>b@?Q?LonLk(~TYDo{F9@cZH z0bE3N{1d9(pY8Y~)U9|@oAqaPosV^0fsv>SccUJv6Xw^bnS75dio0s{d#DwBgc|VQ zr~$i3@4QfCmuq14c+`1`wm&IAfx)=Zs1ask5awDv4>hypI2rfa@tUl=o|)RH4(g%? z*akJ@4yXxqM|GHtY9|dF;3PAUPeDt#3mf4P)GfJ)dIp{#zd#qs1E244iqLARjTJZD}Vm;$2I|Bt zvjBBoi5>saJa1kz@0gEKD^!MBu}Y1->%&m}L^Njob&vh*(1;W4gx+Q!JF%bDN1+IHS(_Wy%=W_(Rpe^%es;RdOJcBmP4GZW2Z)JpWX zdN%6(4^bT~vHb-|+ioN3Aw7jU?;G<9Y67L^g8&6J{D++o>GuW@jk>TE>gU+e>Z4Kj zcnWHu^HFckrRG-DJwA>){vB$Cu2}uHdEX2?rl4ow8EPO6_~JQp-B3TvVW@^Cn=?@Z z%RxP)`KViX5H+*Yr~#fwT~~^FL*7OGDxRQLtjs$ea3Q>9)L=EUK7K^Kh1K_%$IUaS zhA*OK_Jh^$VEOyP>Sbm{Myd9zm{DePtgPREJOwRT7jvMUFcsC&TvSJSsF|(7RNQaJ z|HO*apQ8p4#B%DoI%Y%E%0yee4XVEmlKx!^1ugk_)JPXteKjUfKa9HImL31g4B?Sh z#}TLwqfi5AY{uLEL{z)Us0j>3O=ubhbYZTYu*fVxJyhGRUTmJl@}Cpxy6dQhO3mL; z9X&Uz#(MR-sPkjYIMhHAVp)G5g(N$WVh%#hWF%(cbkwil7HTCzsf1utvn8tIwq{q< zLzjda@DQt~qo4Y8)b*?N{?!t0UNsf_8WFKiw z-X_`P4Wiq&nhYTe$S34w^51P8m0@H839RR9D0#6hwL-qBcR(mfw7M8<qBq_W za)|UJ+E#kFiRLErB{LU;^!J~?4Q`t4e1Vo+oBkYcBkjmIqI>ol=|ObcUTjUQ5N9ql z+h9-frqy@i5fV!}mG9H~vn?jPFWmd2E16I9H~mxc0qIDzRr7Fbuqx?IGHqX)nSrm9 zu|zMj_lUMF9&RqqA_GZ^^y&$eU-5W8BKcGzE|->qK8@A z$7BWZ6K#29I|(L9B+!Ac_GA^&*3iQp#a*O`%qDM<9HMQMNBN)H9ai3meXSgYQ^<0n zUy~*|k7(=W;TB;%?-0L7Dw|0Z#^<+;8PV zTuVlfW!l$k%=FpWu2)7z;iT%Z~o;`8;wBqO*^C}c?so5hW zZa`nZPVo+9`jazr{Auag6WoCR9nj9=8&PL`A@??y+*^OFaCO7mA@_^&e))V~aaN<$ n3dN@ypAC-TDsSK2qWlL1d+(ntx_f4!+Vb{#_2N0rOM?Cd7Jh?* delta 3758 zcmZwJdrX&A9LMp)RZ#;%#VZ#TQ8B!vh$5Bt(=;=XE?9Xt%!t%bQt`r*rI~=45*c{M z@;WU;=S*GNYC11#&T7uYwz5=OHO-Z+=6Zjg-?yzlddBDXI_J5ZbDr~@=l5gZnB6(v z<+$)_$F`evBqb5f{eWkh@xeAZ+BtT)DcBsRV^@18u-K zyn=1;4{U`oG}e^7D22oJM0qll3s41L_tA@ASU5;)BvM6sHtp)T9my|1L%+H zIDl$+v>ne!J%aJbB)Az^i5}{@7Ok0oEus$0v+Rz#lMLjhT(;G7QB#z=f#u zijhCJ)atdU^Y+;OkB~myNz?!vFchzPwxbbsXSc8jqvL}oEI=)m#mFJI1U105s5{<> z8u)fphx<|O9KsHG-ux9cgUxx42^f!hBwl|CS_9*eH^X_T23Mh`cs=S)>rhj<3w7RM zJAN89kaMU3TtrRnx2P%q#ni%5Jq|TvDadu6%cP(ShoHV-hNA|Mhw5-5YRYDz?w}Mk z14~f@t3b_66{?+`sDbZA4QxMh^X@3Fz%MZiCo)Z4_5RmT&;_5M8u%R5(J9n3`wG=j zBdWohr~&?kTAWSW2ak704Xh7pYBN!fU=r#PF2pYAp}y$0VyG8FhZJ<-NzPWoU!dxj z%ipGqe4}{`J)Q8Kop9a!-3();_#K%E zsF_Ja%~S^J`Yby>6!mO#Py?M}$BXUwe5)@*wNshE{HuYr?9c@p?ZmyP_x~{J_|K>{ za0|QQ9owIh7+fPgkx6vfr~!{fT~}ZhnX^$dRBH8giT3{2u|pkvfc&{bd}uLVKs9*9 zyn!0|9W#mrpaxr^&KrR0IAHZrsI@TG>K^J*R-(?U(+RFz%6Bet6xC6Mxdt`R8uSCW^fDY#`a+@p74)*{IW3*dOs6U1L%ypFvHA7%}l`RIj9bw zG-slwd^u{MTdn>f_M?6Vb-tdHj<+*YF^v9QKMLwF6E%SQ%{<#*fV!~A>hrDcnU$zD zRAco$=EtZRI)Q5c9BL*mnAgx#!?!8O2;MCjhq@riOhrvyI)-Dw_K!4kQ3KD%m#`4E z>Mx@1JTx`fUI()?s-GUIJbx7iutSS1fc`VJ`Z!Exe<4OPPF(y$=%zue6&@rjoT}AgLzWR*_A9DfnBljq+lv^8@D( zQfp)$8EX5*BmXHg8U8H2hCOY6J3apeq>7~5PO-tt3-JXjk1|VLk& zr|x_NVS&4cNIvOLwh(Pkk>P%c`}f~zs|-MWX$&E+k~u`rdlu2Asm>%l$S$Hyk8iwR z3O<@XlBMFePM4SGJSnikjUBIWwD^^dzbz~-~ zA)AS|UPM3HX=DbOPfCckP*Uudcy+P4U#9pp-cMi!5?4(d+mO(H2j(`laBn zW)sR|tUeu=kOZsWkN1!q@*MG2@=-zFBKqEbgS<(!jU+FUBGR4=BC#Z!j3(X46XZei zJXt}sts&#cPVy*OO|)f@Lh>@1NZin=Ro_HksyZI?WBq~HvXJ_$xPg)No7)} Date: Tue, 3 Jan 2023 11:22:54 +0800 Subject: [PATCH 13/22] feat: modify certification content #29, #52 --- .../src/components/CodeEditor/CodeEditor.vue | 9 +- frontend/src/language/en/app.po | 46 +- frontend/src/language/messages.pot | 45 +- frontend/src/language/translations.json | 2 +- frontend/src/language/zh_CN/app.mo | Bin 10289 -> 10549 bytes frontend/src/language/zh_CN/app.po | 44 +- frontend/src/language/zh_TW/app.po | 46 +- frontend/src/views/cert/Cert.vue | 30 +- frontend/src/views/domain/cert/Cert.vue | 1 + frontend/src/views/domain/cert/CertInfo.vue | 5 - server/api/cert.go | 470 +++++++++++------- 11 files changed, 438 insertions(+), 260 deletions(-) diff --git a/frontend/src/components/CodeEditor/CodeEditor.vue b/frontend/src/components/CodeEditor/CodeEditor.vue index 16d44e2d8..e208bbaea 100644 --- a/frontend/src/components/CodeEditor/CodeEditor.vue +++ b/frontend/src/components/CodeEditor/CodeEditor.vue @@ -4,16 +4,13 @@ import 'ace-builds/src-noconflict/mode-nginx' import 'ace-builds/src-noconflict/theme-monokai' import {computed} from 'vue' -const props = defineProps<{ - content: string - defaultHeight?: string -}>() +const props = defineProps(['content', 'defaultHeight']) const emit = defineEmits(['update:content']) const value = computed({ get() { - return props.content + return props.content ?? '' }, set(value) { emit('update:content', value) @@ -27,7 +24,7 @@ const value = computed({ lang="nginx" theme="monokai" :style="{ - minHeight: props.defaultHeight || '100vh' + minHeight: defaultHeight || '100vh' }"/> diff --git a/frontend/src/language/en/app.po b/frontend/src/language/en/app.po index 4e0ad27f9..bf99e1c85 100644 --- a/frontend/src/language/en/app.po +++ b/frontend/src/language/en/app.po @@ -17,7 +17,7 @@ msgstr "About" msgid "Access Logs" msgstr "" -#: src/views/cert/Cert.vue:75 src/views/config/config.ts:36 +#: src/views/cert/Cert.vue:78 src/views/config/config.ts:36 #: src/views/domain/DomainList.vue:47 src/views/user/User.vue:43 msgid "Action" msgstr "Action" @@ -68,10 +68,14 @@ msgstr "Are you sure you want to remove this directive?" msgid "Auto" msgstr "" -#: src/views/cert/Cert.vue:38 +#: src/views/cert/Cert.vue:41 msgid "Auto Cert" msgstr "" +#: src/views/cert/Cert.vue:8 +msgid "Auto cert is enabled, please do not modify this certification." +msgstr "" + #: src/views/nginx_log/NginxLog.vue:4 msgid "Auto Refresh" msgstr "" @@ -123,15 +127,15 @@ msgstr "Build with" msgid "Cancel" msgstr "Cancel" -#: src/views/domain/cert/CertInfo.vue:24 +#: src/views/domain/cert/CertInfo.vue:19 msgid "Certificate has expired" msgstr "Certificate has expired" -#: src/views/domain/cert/CertInfo.vue:28 +#: src/views/domain/cert/CertInfo.vue:23 msgid "Certificate is valid" msgstr "Certificate is valid" -#: src/views/domain/cert/CertInfo.vue:14 +#: src/views/cert/Cert.vue:12 src/views/domain/cert/Cert.vue:31 msgid "Certificate Status" msgstr "Certificate Status" @@ -232,7 +236,7 @@ msgstr "Directives" msgid "Disable auto-renewal failed for %{name}" msgstr "Disable auto-renewal failed for %{name}" -#: src/views/cert/Cert.vue:48 src/views/domain/DomainEdit.vue:10 +#: src/views/cert/Cert.vue:51 src/views/domain/DomainEdit.vue:10 #: src/views/domain/DomainEdit.vue:9 src/views/domain/DomainList.vue:16 #: src/views/domain/DomainList.vue:34 src/views/domain/DomainList.vue:7 #: src/views/domain/DomainList.vue:8 src/views/domain/DomainList.vue:9 @@ -247,7 +251,7 @@ msgstr "Disabled successfully" msgid "Disk IO" msgstr "Disk IO" -#: src/views/cert/Cert.vue:29 +#: src/views/cert/Cert.vue:32 msgid "Domain" msgstr "" @@ -283,7 +287,7 @@ msgstr "Enable failed" msgid "Enable TLS" msgstr "Enable TLS" -#: src/views/cert/Cert.vue:45 src/views/domain/DomainEdit.vue:33 +#: src/views/cert/Cert.vue:48 src/views/domain/DomainEdit.vue:33 #: src/views/domain/DomainEdit.vue:6 src/views/domain/DomainEdit.vue:7 #: src/views/domain/DomainList.vue:10 src/views/domain/DomainList.vue:11 #: src/views/domain/DomainList.vue:12 src/views/domain/DomainList.vue:19 @@ -304,7 +308,7 @@ msgstr "Encrypt website with Let's Encrypt" msgid "Error Logs" msgstr "" -#: src/views/domain/cert/CertInfo.vue:17 +#: src/views/domain/cert/CertInfo.vue:12 msgid "Expiration Date: %{date}" msgstr "Expiration Date: %{date}" @@ -377,7 +381,7 @@ msgstr "Install" msgid "Install successfully" msgstr "Enabled successfully" -#: src/views/domain/cert/CertInfo.vue:15 +#: src/views/domain/cert/CertInfo.vue:10 msgid "Intermediate Certification Authorities: %{issuer}" msgstr "Intermediate Certification Authorities: %{issuer}" @@ -467,7 +471,7 @@ msgstr "Modify Config" msgid "Modify Config" msgstr "Modify Config" -#: src/views/cert/Cert.vue:13 src/views/config/config.ts:9 +#: src/views/cert/Cert.vue:16 src/views/config/config.ts:9 #: src/views/domain/DomainEdit.vue:36 src/views/domain/DomainList.vue:15 msgid "Name" msgstr "Name" @@ -515,7 +519,7 @@ msgstr "No" msgid "Not Found" msgstr "Not Found" -#: src/views/domain/cert/CertInfo.vue:19 +#: src/views/domain/cert/CertInfo.vue:14 msgid "Not Valid Before: %{date}" msgstr "Not Valid Before: %{date}" @@ -705,16 +709,26 @@ msgstr "Sites List" msgid "Sites List" msgstr "Sites List" -#: src/views/cert/Cert.vue:62 +#: src/views/cert/Cert.vue:65 #, fuzzy msgid "SSL Certificate Key Path" msgstr "Certificate Status" -#: src/views/cert/Cert.vue:55 +#: src/views/cert/Cert.vue:58 #, fuzzy msgid "SSL Certificate Path" msgstr "Certificate Status" +#: src/views/cert/Cert.vue:19 +#, fuzzy +msgid "SSL Certification Content" +msgstr "Certificate Status" + +#: src/views/cert/Cert.vue:22 +#, fuzzy +msgid "SSL Certification Key Content" +msgstr "Certificate Status" + #: src/views/domain/DomainList.vue:24 msgid "Status" msgstr "Status" @@ -723,7 +737,7 @@ msgstr "Status" msgid "Storage" msgstr "Storage" -#: src/views/domain/cert/CertInfo.vue:16 +#: src/views/domain/cert/CertInfo.vue:11 msgid "Subject Name: %{name}" msgstr "Subject Name: %{name}" @@ -768,7 +782,7 @@ msgstr "" msgid "Type" msgstr "" -#: src/views/cert/Cert.vue:69 src/views/config/config.ts:29 +#: src/views/cert/Cert.vue:72 src/views/config/config.ts:29 #: src/views/domain/DomainList.vue:41 src/views/user/User.vue:37 msgid "Updated at" msgstr "Updated at" diff --git a/frontend/src/language/messages.pot b/frontend/src/language/messages.pot index d4be31a0e..dfa45ece2 100644 --- a/frontend/src/language/messages.pot +++ b/frontend/src/language/messages.pot @@ -11,7 +11,7 @@ msgstr "" msgid "Access Logs" msgstr "" -#: src/views/cert/Cert.vue:75 +#: src/views/cert/Cert.vue:78 #: src/views/config/config.ts:36 #: src/views/domain/DomainList.vue:47 #: src/views/user/User.vue:43 @@ -64,10 +64,14 @@ msgstr "" msgid "Auto" msgstr "" -#: src/views/cert/Cert.vue:38 +#: src/views/cert/Cert.vue:41 msgid "Auto Cert" msgstr "" +#: src/views/cert/Cert.vue:8 +msgid "Auto cert is enabled, please do not modify this certification." +msgstr "" + #: src/views/nginx_log/NginxLog.vue:4 msgid "Auto Refresh" msgstr "" @@ -121,15 +125,16 @@ msgstr "" msgid "Cancel" msgstr "" -#: src/views/domain/cert/CertInfo.vue:24 +#: src/views/domain/cert/CertInfo.vue:19 msgid "Certificate has expired" msgstr "" -#: src/views/domain/cert/CertInfo.vue:28 +#: src/views/domain/cert/CertInfo.vue:23 msgid "Certificate is valid" msgstr "" -#: src/views/domain/cert/CertInfo.vue:14 +#: src/views/cert/Cert.vue:12 +#: src/views/domain/cert/Cert.vue:31 msgid "Certificate Status" msgstr "" @@ -231,7 +236,7 @@ msgstr "" msgid "Disable auto-renewal failed for %{name}" msgstr "" -#: src/views/cert/Cert.vue:48 +#: src/views/cert/Cert.vue:51 #: src/views/domain/DomainEdit.vue:10 #: src/views/domain/DomainEdit.vue:9 #: src/views/domain/DomainList.vue:16 @@ -251,7 +256,7 @@ msgstr "" msgid "Disk IO" msgstr "" -#: src/views/cert/Cert.vue:29 +#: src/views/cert/Cert.vue:32 msgid "Domain" msgstr "" @@ -289,7 +294,7 @@ msgstr "" msgid "Enable TLS" msgstr "" -#: src/views/cert/Cert.vue:45 +#: src/views/cert/Cert.vue:48 #: src/views/domain/DomainEdit.vue:33 #: src/views/domain/DomainEdit.vue:6 #: src/views/domain/DomainEdit.vue:7 @@ -316,7 +321,7 @@ msgstr "" msgid "Error Logs" msgstr "" -#: src/views/domain/cert/CertInfo.vue:17 +#: src/views/domain/cert/CertInfo.vue:12 msgid "Expiration Date: %{date}" msgstr "" @@ -393,7 +398,7 @@ msgstr "" msgid "Install successfully" msgstr "" -#: src/views/domain/cert/CertInfo.vue:15 +#: src/views/domain/cert/CertInfo.vue:10 msgid "Intermediate Certification Authorities: %{issuer}" msgstr "" @@ -481,7 +486,7 @@ msgstr "" msgid "Modify Config" msgstr "" -#: src/views/cert/Cert.vue:13 +#: src/views/cert/Cert.vue:16 #: src/views/config/config.ts:9 #: src/views/domain/DomainEdit.vue:36 #: src/views/domain/DomainList.vue:15 @@ -533,7 +538,7 @@ msgstr "" msgid "Not Found" msgstr "" -#: src/views/domain/cert/CertInfo.vue:19 +#: src/views/domain/cert/CertInfo.vue:14 msgid "Not Valid Before: %{date}" msgstr "" @@ -729,14 +734,22 @@ msgstr "" msgid "Sites List" msgstr "" -#: src/views/cert/Cert.vue:62 +#: src/views/cert/Cert.vue:65 msgid "SSL Certificate Key Path" msgstr "" -#: src/views/cert/Cert.vue:55 +#: src/views/cert/Cert.vue:58 msgid "SSL Certificate Path" msgstr "" +#: src/views/cert/Cert.vue:19 +msgid "SSL Certification Content" +msgstr "" + +#: src/views/cert/Cert.vue:22 +msgid "SSL Certification Key Content" +msgstr "" + #: src/views/domain/DomainList.vue:24 msgid "Status" msgstr "" @@ -745,7 +758,7 @@ msgstr "" msgid "Storage" msgstr "" -#: src/views/domain/cert/CertInfo.vue:16 +#: src/views/domain/cert/CertInfo.vue:11 msgid "Subject Name: %{name}" msgstr "" @@ -786,7 +799,7 @@ msgstr "" msgid "Type" msgstr "" -#: src/views/cert/Cert.vue:69 +#: src/views/cert/Cert.vue:72 #: src/views/config/config.ts:29 #: src/views/domain/DomainList.vue:41 #: src/views/user/User.vue:37 diff --git a/frontend/src/language/translations.json b/frontend/src/language/translations.json index 53f01b49a..bcb06048f 100644 --- a/frontend/src/language/translations.json +++ b/frontend/src/language/translations.json @@ -1 +1 @@ -{"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Auto":"自动","Auto Cert":"自动更新","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Certification":"证书","Comments":"注释","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Development Mode":"开发模式","Dir":"目录","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Domain":"域名","Domain Config Created Successfully":"域名配置文件创建成功","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","File":"文件","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","HTTP Challenge Port":"HTTP Challenge 监听端口","HTTP Port":"HTTP 监听端口","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Jwt Secret":"Jwt 密钥","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","Next":"下一步","Nginx Access Log Path":"Nginx 访问日志路径","Nginx Error Log Path":"Nginx 错误日志路径","Nginx Log":"Nginx 日志","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:当前配置中的 server_name 必须为需要申请证书的域名。","Obtaining certificate":"正在获取证书","OK":"确定","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reloading nginx":"正在重载 Nginx","Reset":"重置","Run Mode":"运行模式","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","SSL Certificate Key Path":"SSL证书密钥路径","SSL Certificate Path":"SSL证书路径","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","Table":"列表","Terminal":"终端","Terminal Start Command":"终端启动命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Type":"类型","Updated at":"修改时间","Updated successfully":"更新成功","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","License":{"Project":"开源许可"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"Note: The server_name in the current configuration must be the domain name you need to get the certificate.","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}},"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Auto":"自動","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Comments":"註釋","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Development Mode":"開發模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Domain Config Created Successfully":"域名配置文件創建成功","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error Logs":"錯誤日志","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","Next":"下一步","Nginx Log":"Nginx 日誌","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:當前配置中的 server_name 必須為需要申請證書的域名。","Obtaining certificate":"正在獲取證書,請稍等...","OK":"確定","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reloading nginx":"重载 Nginx","Reset":"重設","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","Table":"表格","Terminal":"終端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Updated at":"修改時間","Updated successfully":"已成功更新","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","License":{"Project":"開源軟體授權條款"}}} \ No newline at end of file +{"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Auto":"自动","Auto Cert":"自动更新","Auto cert is enabled, please do not modify this certification.":"自动更新已启用,请勿修改此证书配置。","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Certification":"证书","Comments":"注释","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Development Mode":"开发模式","Dir":"目录","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Domain":"域名","Domain Config Created Successfully":"域名配置文件创建成功","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","File":"文件","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","HTTP Challenge Port":"HTTP Challenge 监听端口","HTTP Port":"HTTP 监听端口","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Jwt Secret":"Jwt 密钥","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","Next":"下一步","Nginx Access Log Path":"Nginx 访问日志路径","Nginx Error Log Path":"Nginx 错误日志路径","Nginx Log":"Nginx 日志","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:当前配置中的 server_name 必须为需要申请证书的域名。","Obtaining certificate":"正在获取证书","OK":"确定","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reloading nginx":"正在重载 Nginx","Reset":"重置","Run Mode":"运行模式","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","SSL Certificate Key Path":"SSL证书密钥路径","SSL Certificate Path":"SSL证书路径","SSL Certification Content":"SSL证书内容","SSL Certification Key Content":"SSL证书密钥内容","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","Table":"列表","Terminal":"终端","Terminal Start Command":"终端启动命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Type":"类型","Updated at":"修改时间","Updated successfully":"更新成功","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","License":{"Project":"开源许可"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"Note: The server_name in the current configuration must be the domain name you need to get the certificate.","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}},"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Auto":"自動","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Comments":"註釋","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Development Mode":"開發模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Domain Config Created Successfully":"域名配置文件創建成功","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error Logs":"錯誤日志","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","Next":"下一步","Nginx Log":"Nginx 日誌","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:當前配置中的 server_name 必須為需要申請證書的域名。","Obtaining certificate":"正在獲取證書,請稍等...","OK":"確定","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reloading nginx":"重载 Nginx","Reset":"重設","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","Table":"表格","Terminal":"終端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Updated at":"修改時間","Updated successfully":"已成功更新","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","License":{"Project":"開源軟體授權條款"}}} \ No newline at end of file diff --git a/frontend/src/language/zh_CN/app.mo b/frontend/src/language/zh_CN/app.mo index 782e3912e57c301d4c1ffd0a3f628a10cf8b8db7..cf06af7f19c2a91182653a751670ac0b47eb3d89 100644 GIT binary patch delta 4111 zcmZYB3v|wP9LMpW8Ai+Fw&a!v8LQ4=SWaZo8b-QJ)5zdD`M|2&`P_5c0;zyI&|`~Uv`|Fi8J`DSA1 zn|hIJ9b1?*CA+FQcM*r)z!zJT&pE1GO;nW+t78+aiY>7|#$q%kU=$9t@<{Yk9*^xY z3)^7{MmiUAr`V}U#TirwKjJ-j4O?KhI$j6kkQ3ZIRQrX<$K~=>3ky)^7g;%MzJogN zBhiEYjGDk@WJq@v8!^7C$tbF5g<8_is1v)PI_`^Ya2RT0k6{dEp(c`t>UbTt#6r~h z?;{`giIvZq7f}8Fh9S)?f*YtSk3)6X6}2M0P#r#iI$;jpjM=CG3#_~u8&ckjt?@I| z3S2|2++V2nH`1vtpn=(}0qd`aA(jeV;b^3-TY$QPRj7^%P!rpPd|WYK9dSQ4$BU>5 z`dF4m*ckQDc1BGg0X6VoRKJOKJSm3t*V0d-g4^LTa2e*HPONv6_fWMk+o7(cJFafM_`Qy(!hoprIlZI+HA4A$%%8u?$ zKC0tVycLh3I{FpW?oYGUEnFSthN$+#%~`1St5NM=G>gozdC)v^3+u0?Izfe&t{m0D z_txMt>R$hant5Gbb{%hFwnYup-pV~t{q?i*aMXFDQSAb#-;LRJe2dm!565d%=w7~Q z2Tr0Mo-@d8c0Z#!sO|SA(8O$M#-UcCgOw9e?Z=|}pMskBEaY0;9Mr>_A7V!hH=CuX zE7)g#fa>^DRJ&hL9aW)HcR?86D&f`3%Pyl=%@2t z)a!8!wPYu}2CfX%;Sc6joKLwLy{kUkTw$(5O=uhH!gg5sAZj8XSouVyA?LnjM;%p| zSIh`5TNCl2maLI^C#wAr)IblR2AY7nvLKGY96Np-t5W_NHG$Js|FdL#_d7dUnkqbj z>M$BLV0|+lwdDO#11DQK9XnCZMYVs&j(=g6p$5K;>h}t20)LpkSk_+$TC$^#<4{-7 z1$9M3%_OT&!|K#$quMVu^HC33p_O-=@1a)k7*@xVsD96wKgDwY)lmeGu=JTtQ76Qi z9Z(bNijg?X>J!bes4JU@voHhsxH7)9GSO|l{#u*ysPQ_rW&O3&n+iRI!%#DR*vbL) zQ_et5C=a!y1*o@SBkI;1vg4<)a$w}+qT{%&s5aWT)9w}W8W~D%*ZnUg-AMJU9s+VY5g@9!m3h_?InrSVfpKN27dNHWp3(ZkKd zOfs5`usUAhf45ESjUwyG>qOfFqy~v3vx&Bvq%N6A`VwuSu6*g|lwZ}#EsO6Jq=i>> z*|?chBli*g-M@>hCfb^LxShC_yg?o(gUFLa+XN4HCl=cNIvnO*zxR&Lq~bZkKQnG2 zd5XM5?jhP1lg5>M-aEd5{Ym5ztE+_%lO816>O>1Q3TBpB{WmfBq>7-klZy%amy7IGqkvhE2yccnft!v zuGrXAmVZQ}nKPQ>nEiofqm$zhGnqC`GKV~{}pZj^=v%K3m_rPa4XR>{j%{`kP z+iB98>P7MAc(32D@Na%)~@2 zLXUGkcY;DgcAQ0B@D;Yh%NT=?kP}@VZZvAZx!4>h zVef*OFQnR6)^it2DMYC=OW9><^t zP>fvSO0XqvQ=R_ZISN|J3e<&{Q4Qa~j#!BrSP-LXfuX2@#GxAQg6*+8>iQAL$Bnmo zfmwuVcNJ=28_}nke?dVFUczv^hHCIW>H;q}I10m19VS>k8MTyyF%Bo9R-hEMa_dm% z??O%Bpm`GY44e;R{WZe}?BL^?(7R^P9@S6+YG6so$MxbX2{W-RE=CP-4{Aw|p&r%> z)BvuaI{q2e?yq*d3UwJcDZP)C!x+uv;FBl3Jk{OqDEMN0a#@9C8(LL#_4#_jyGf7^~{8$I*39I zFcCH59;gZQLv@&eY9||`ahmB{K|xEn51+#ms9SOc^$a{let|B62S5$Rqn0=sHPc?G zrA$Sgmt)5#pawD(`M5cJX`-d50qsUs+UE{X&@Cu8E6iJ{rGAKNs0MXmAk)x`C>S-M z2-E;#Q7hOTHKBf}6-h@8G#j;2BT?co7r z40YZ)JN~74$-HUaGpkW6RD)Wv25tP;hoJfiYs32M9>=glBTlvx2AG5F#35E6hiY(= z)$>u;EkHH667_!AWXHclJrh?^FQ{9#|6kNI<7vzKv-++DH%JY1L(QF!Bf}Vk=sDVWD#dGHRqJEa6Pz_Bt=b{Ey zhfFn%M@-!ozm_ zFRV}f8EOClET^t(VYWuCOsv%tQT_Fh^zSk$XvwFbM!MAM>oJ-7anuEO?fBnj5RbGv z4nuVqi5fr~Gs*U+q1w$rO<*KyLbK4P3ybW89&xkR(wLbNQ}w5)?jKeB)fBm2o%a+*vdhe#Ll z1}Pw~5#6@+WCU4CJ|ZuW|8JYAj3QHs?_<73lDe(L3M)*#1H2^7>SDN+U&J?w-gv9X zF*1Z`TkFTYYi={2H;XVpfB*U0;AYv*I<(~4^yhdN=|(0K-Lsd;D@3=gZfk3W1aq00 zi2cdyR^N*!NIdCPyHD%SwvzC^aPN^6QcUzW{S)#&=}ELT_Tx5SBQk(YvVGZR9==K@ z61~XYA=-BMaSL%C8A>v(|Jqlu9d|n^zlXXN}Yd`KJ?jxtjd@_&}5^dxB)c&d6W96+l*vgSOgRCa{ zHEEKIiMGCe+;VK`Kg92m%62lIyiK&}l{uR9At9u0i=q%ml5NLyJW3{5J) template.push($gettext('Enabled')) } else { - template.push() + template.push() template.push($gettext('Disabled')) } return h('div', template) @@ -80,7 +83,30 @@ const columns = [{ diff --git a/frontend/src/views/domain/ngx_conf/LocationEditor.vue b/frontend/src/views/domain/ngx_conf/LocationEditor.vue index 507ce3415..8ac93fe1c 100644 --- a/frontend/src/views/domain/ngx_conf/LocationEditor.vue +++ b/frontend/src/views/domain/ngx_conf/LocationEditor.vue @@ -7,7 +7,7 @@ import draggable from 'vuedraggable' const {$gettext} = useGettext() -const props = defineProps(['locations']) +const props = defineProps(['locations', 'readonly']) let location = reactive({ comments: '', @@ -52,7 +52,7 @@ function remove(index: number) { {{ $gettext('Location') }} - -
+ +
diff --git a/frontend/src/views/domain/ngx_conf/directive/DirectiveEditor.vue b/frontend/src/views/domain/ngx_conf/directive/DirectiveEditor.vue index c2d9aa651..9b7a4e482 100644 --- a/frontend/src/views/domain/ngx_conf/directive/DirectiveEditor.vue +++ b/frontend/src/views/domain/ngx_conf/directive/DirectiveEditor.vue @@ -7,9 +7,7 @@ import DirectiveEditorItem from '@/views/domain/ngx_conf/directive/DirectiveEdit const {$gettext} = useGettext() -const props = defineProps<{ - ngx_directives: any[] -}>() +const props = defineProps(['ngx_directives', 'readonly']) const adding = ref(false) @@ -38,11 +36,13 @@ function onSave(idx: number) { + :ngx_directives="ngx_directives" + :readonly="readonly" + /> - + \ No newline at end of file diff --git a/frontend/src/components/StdDataEntry/compontents/StdSelect.vue b/frontend/src/components/StdDataEntry/compontents/StdSelect.vue deleted file mode 100644 index 75b8a3581..000000000 --- a/frontend/src/components/StdDataEntry/compontents/StdSelect.vue +++ /dev/null @@ -1,45 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend/src/components/StdDataEntry/compontents/StdSelector.vue b/frontend/src/components/StdDataEntry/compontents/StdSelector.vue deleted file mode 100644 index efa662f7c..000000000 --- a/frontend/src/components/StdDataEntry/compontents/StdSelector.vue +++ /dev/null @@ -1,137 +0,0 @@ - - - - - diff --git a/frontend/src/language/en/app.po b/frontend/src/language/en/app.po index 8172f67f8..7ff0cd3ef 100644 --- a/frontend/src/language/en/app.po +++ b/frontend/src/language/en/app.po @@ -91,11 +91,11 @@ msgstr "" msgid "Auto Refresh" msgstr "" -#: src/views/domain/cert/IssueCert.vue:72 +#: src/views/domain/cert/IssueCert.vue:71 msgid "Auto-renewal disabled for %{name}" msgstr "Auto-renewal disabled for %{name}" -#: src/views/domain/cert/IssueCert.vue:66 +#: src/views/domain/cert/IssueCert.vue:65 msgid "Auto-renewal enabled for %{name}" msgstr "Auto-renewal enabled for %{name}" @@ -134,7 +134,6 @@ msgstr "Build with" #: src/components/StdDataDisplay/StdBatchEdit.vue:7 #: src/components/StdDataDisplay/StdCurd.vue:27 #: src/components/StdDataEntry/components/StdSelector.vue:11 -#: src/components/StdDataEntry/compontents/StdSelector.vue:11 msgid "Cancel" msgstr "Cancel" @@ -146,7 +145,7 @@ msgstr "Certificate has expired" msgid "Certificate is valid" msgstr "Certificate is valid" -#: src/views/cert/Cert.vue:12 src/views/domain/cert/Cert.vue:31 +#: src/views/cert/Cert.vue:12 src/views/domain/cert/Cert.vue:35 msgid "Certificate Status" msgstr "Certificate Status" @@ -155,6 +154,13 @@ msgstr "Certificate Status" msgid "Certification" msgstr "Certificate is valid" +#: src/views/domain/cert/ChangeCert.vue:2 +#: src/views/domain/cert/ChangeCert.vue:3 +#: src/views/domain/cert/ChangeCert.vue:5 +#, fuzzy +msgid "Change Certificate" +msgstr "Certificate is valid" + #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:34 #: src/views/domain/ngx_conf/LocationEditor.vue:31 #: src/views/domain/ngx_conf/LocationEditor.vue:47 @@ -267,7 +273,7 @@ msgstr "Directive" msgid "Directives" msgstr "Directives" -#: src/views/domain/cert/IssueCert.vue:74 +#: src/views/domain/cert/IssueCert.vue:73 msgid "Disable auto-renewal failed for %{name}" msgstr "Disable auto-renewal failed for %{name}" @@ -310,7 +316,7 @@ msgstr "Edit Site" msgid "Email (*)" msgstr "Email (*)" -#: src/views/domain/cert/IssueCert.vue:68 +#: src/views/domain/cert/IssueCert.vue:67 msgid "Enable auto-renewal failed for %{name}" msgstr "Enable auto-renewal failed for %{name}" @@ -397,7 +403,6 @@ msgid "Format successfully" msgstr "Saved successfully" #: src/components/StdDataEntry/components/StdPassword.vue:42 -#: src/components/StdDataEntry/compontents/StdPassword.vue:42 msgid "Generate" msgstr "" @@ -405,7 +410,7 @@ msgstr "" msgid "Generating private key for registering account" msgstr "" -#: src/views/domain/cert/IssueCert.vue:97 +#: src/views/domain/cert/IssueCert.vue:96 msgid "Getting the certificate, please wait..." msgstr "Getting the certificate, please wait..." @@ -478,7 +483,7 @@ msgstr "Login successful" msgid "Logout successful" msgstr "Logout successful" -#: src/views/domain/cert/IssueCert.vue:210 +#: src/views/domain/cert/IssueCert.vue:211 msgid "" "Make sure you have configured a reverse proxy for .well-known directory to " "HTTPChallengePort (default: 9180) before getting the certificate." @@ -578,13 +583,9 @@ msgstr "Not Found" msgid "Not Valid Before: %{date}" msgstr "Not Valid Before: %{date}" -#: src/views/domain/cert/IssueCert.vue:202 -msgid "" -"Note: The server_name in the current configuration must be the domain name " -"you need to get the certificate." +#: src/views/domain/cert/IssueCert.vue:38 +msgid "Note" msgstr "" -"Note: The server_name in the current configuration must be the domain name " -"you need to get the certificate." #: src/language/constants.ts:16 src/views/domain/cert/IssueCert.vue:3 msgid "Obtaining certificate" @@ -594,7 +595,6 @@ msgstr "" #: src/components/StdDataDisplay/StdCurd.vue:28 #: src/components/StdDataDisplay/StdTable.vue:53 #: src/components/StdDataEntry/components/StdSelector.vue:12 -#: src/components/StdDataEntry/compontents/StdSelector.vue:12 #: src/views/domain/DomainList.vue:25 msgid "OK" msgstr "" @@ -719,7 +719,6 @@ msgid "Saved successfully" msgstr "Saved successfully" #: src/components/StdDataEntry/components/StdSelector.vue:13 -#: src/components/StdDataEntry/compontents/StdSelector.vue:13 msgid "Selector" msgstr "" @@ -742,11 +741,11 @@ msgstr "Server error" msgid "Server Info" msgstr "Server Info" -#: src/views/domain/cert/IssueCert.vue:29 +#: src/views/domain/cert/IssueCert.vue:30 msgid "server_name not found in directives" msgstr "server_name not found in directives" -#: src/views/domain/cert/IssueCert.vue:196 src/views/domain/DomainAdd.vue:111 +#: src/views/domain/cert/IssueCert.vue:195 src/views/domain/DomainAdd.vue:111 msgid "server_name parameter is required" msgstr "server_name parameter is required" @@ -813,7 +812,7 @@ msgstr "Terminal" msgid "Terminal Start Command" msgstr "" -#: src/views/domain/cert/IssueCert.vue:206 +#: src/views/domain/cert/IssueCert.vue:207 msgid "" "The certificate for the domain will be checked every hour, and will be " "renewed if it has been more than 1 month since it was last issued." @@ -825,6 +824,15 @@ msgstr "" msgid "The filename cannot contain the following characters: %{c}" msgstr "The filename cannot contain the following characters: %{c}" +#: src/views/domain/cert/IssueCert.vue:203 +#, fuzzy +msgid "" +"The server_name in the current configuration must be the domain name you " +"need to get the certificate." +msgstr "" +"Note: The server_name in the current configuration must be the domain name " +"you need to get the certificate." + #: src/language/constants.ts:6 msgid "The username or password is incorrect" msgstr "" diff --git a/frontend/src/language/messages.pot b/frontend/src/language/messages.pot index ff0789015..0dbed548a 100644 --- a/frontend/src/language/messages.pot +++ b/frontend/src/language/messages.pot @@ -87,11 +87,11 @@ msgstr "" msgid "Auto Refresh" msgstr "" -#: src/views/domain/cert/IssueCert.vue:72 +#: src/views/domain/cert/IssueCert.vue:71 msgid "Auto-renewal disabled for %{name}" msgstr "" -#: src/views/domain/cert/IssueCert.vue:66 +#: src/views/domain/cert/IssueCert.vue:65 msgid "Auto-renewal enabled for %{name}" msgstr "" @@ -132,7 +132,6 @@ msgstr "" #: src/components/StdDataDisplay/StdBatchEdit.vue:7 #: src/components/StdDataDisplay/StdCurd.vue:27 #: src/components/StdDataEntry/components/StdSelector.vue:11 -#: src/components/StdDataEntry/compontents/StdSelector.vue:11 msgid "Cancel" msgstr "" @@ -145,7 +144,7 @@ msgid "Certificate is valid" msgstr "" #: src/views/cert/Cert.vue:12 -#: src/views/domain/cert/Cert.vue:31 +#: src/views/domain/cert/Cert.vue:35 msgid "Certificate Status" msgstr "" @@ -154,6 +153,12 @@ msgstr "" msgid "Certification" msgstr "" +#: src/views/domain/cert/ChangeCert.vue:2 +#: src/views/domain/cert/ChangeCert.vue:3 +#: src/views/domain/cert/ChangeCert.vue:5 +msgid "Change Certificate" +msgstr "" + #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:34 #: src/views/domain/ngx_conf/LocationEditor.vue:31 #: src/views/domain/ngx_conf/LocationEditor.vue:47 @@ -266,7 +271,7 @@ msgstr "" msgid "Directives" msgstr "" -#: src/views/domain/cert/IssueCert.vue:74 +#: src/views/domain/cert/IssueCert.vue:73 msgid "Disable auto-renewal failed for %{name}" msgstr "" @@ -316,7 +321,7 @@ msgstr "" msgid "Email (*)" msgstr "" -#: src/views/domain/cert/IssueCert.vue:68 +#: src/views/domain/cert/IssueCert.vue:67 msgid "Enable auto-renewal failed for %{name}" msgstr "" @@ -411,7 +416,6 @@ msgid "Format successfully" msgstr "" #: src/components/StdDataEntry/components/StdPassword.vue:42 -#: src/components/StdDataEntry/compontents/StdPassword.vue:42 msgid "Generate" msgstr "" @@ -419,7 +423,7 @@ msgstr "" msgid "Generating private key for registering account" msgstr "" -#: src/views/domain/cert/IssueCert.vue:97 +#: src/views/domain/cert/IssueCert.vue:96 msgid "Getting the certificate, please wait..." msgstr "" @@ -492,7 +496,7 @@ msgstr "" msgid "Logout successful" msgstr "" -#: src/views/domain/cert/IssueCert.vue:210 +#: src/views/domain/cert/IssueCert.vue:211 msgid "Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate." msgstr "" @@ -592,8 +596,8 @@ msgstr "" msgid "Not Valid Before: %{date}" msgstr "" -#: src/views/domain/cert/IssueCert.vue:202 -msgid "Note: The server_name in the current configuration must be the domain name you need to get the certificate." +#: src/views/domain/cert/IssueCert.vue:38 +msgid "Note" msgstr "" #: src/language/constants.ts:16 @@ -605,7 +609,6 @@ msgstr "" #: src/components/StdDataDisplay/StdCurd.vue:28 #: src/components/StdDataDisplay/StdTable.vue:53 #: src/components/StdDataEntry/components/StdSelector.vue:12 -#: src/components/StdDataEntry/compontents/StdSelector.vue:12 #: src/views/domain/DomainList.vue:25 msgid "OK" msgstr "" @@ -734,7 +737,6 @@ msgid "Saved successfully" msgstr "" #: src/components/StdDataEntry/components/StdSelector.vue:13 -#: src/components/StdDataEntry/compontents/StdSelector.vue:13 msgid "Selector" msgstr "" @@ -762,11 +764,11 @@ msgstr "" msgid "Server Info" msgstr "" -#: src/views/domain/cert/IssueCert.vue:29 +#: src/views/domain/cert/IssueCert.vue:30 msgid "server_name not found in directives" msgstr "" -#: src/views/domain/cert/IssueCert.vue:196 +#: src/views/domain/cert/IssueCert.vue:195 #: src/views/domain/DomainAdd.vue:111 msgid "server_name parameter is required" msgstr "" @@ -829,7 +831,7 @@ msgstr "" msgid "Terminal Start Command" msgstr "" -#: src/views/domain/cert/IssueCert.vue:206 +#: src/views/domain/cert/IssueCert.vue:207 msgid "The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued." msgstr "" @@ -837,6 +839,10 @@ msgstr "" msgid "The filename cannot contain the following characters: %{c}" msgstr "" +#: src/views/domain/cert/IssueCert.vue:203 +msgid "The server_name in the current configuration must be the domain name you need to get the certificate." +msgstr "" + #: src/language/constants.ts:6 msgid "The username or password is incorrect" msgstr "" diff --git a/frontend/src/language/translations.json b/frontend/src/language/translations.json index 2ad4d8268..956c18db5 100644 --- a/frontend/src/language/translations.json +++ b/frontend/src/language/translations.json @@ -1 +1 @@ -{"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"Note: The server_name in the current configuration must be the domain name you need to get the certificate.","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}},"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Author":"作者","Auto":"自动","Auto Cert":"自动更新","Auto cert is enabled, please do not modify this certification.":"自动更新已启用,请勿修改此证书配置。","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Certification":"证书","Comments":"注释","Config Templates":"配置","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Custom":"自定义","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Description":"描述","Development Mode":"开发模式","Dir":"目录","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Domain":"域名","Domain Config Created Successfully":"域名配置文件创建成功","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","File":"文件","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Format Code":"代码格式化","Format error %{msg}":"保存错误 %{msg}","Format successfully":"保存成功","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","HTTP Challenge Port":"HTTP Challenge 监听端口","HTTP Port":"HTTP 监听端口","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Jwt Secret":"Jwt 密钥","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Multi-line Directive":"单行指令","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","Next":"下一步","Nginx Access Log Path":"Nginx 访问日志路径","Nginx Error Log Path":"Nginx 错误日志路径","Nginx Log":"Nginx 日志","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:当前配置中的 server_name 必须为需要申请证书的域名。","Obtaining certificate":"正在获取证书","OK":"确定","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reloading nginx":"正在重载 Nginx","Reset":"重置","Run Mode":"运行模式","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","SSL Certificate Key Path":"SSL证书密钥路径","SSL Certificate Path":"SSL证书路径","SSL Certification Content":"SSL证书内容","SSL Certification Key Content":"SSL证书密钥内容","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","Table":"列表","Terminal":"终端","Terminal Start Command":"终端启动命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Type":"类型","Updated at":"修改时间","Updated successfully":"更新成功","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","View":"查看","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","License":{"Project":"开源许可"}},"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Auto":"自動","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Comments":"註釋","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Development Mode":"開發模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Domain Config Created Successfully":"域名配置文件創建成功","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error Logs":"錯誤日志","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","Next":"下一步","Nginx Log":"Nginx 日誌","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Note: The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:當前配置中的 server_name 必須為需要申請證書的域名。","Obtaining certificate":"正在獲取證書,請稍等...","OK":"確定","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reloading nginx":"重载 Nginx","Reset":"重設","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","Table":"表格","Terminal":"終端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Updated at":"修改時間","Updated successfully":"已成功更新","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","License":{"Project":"開源軟體授權條款"}}} \ No newline at end of file +{"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Author":"作者","Auto":"自动","Auto Cert":"自动更新","Auto cert is enabled, please do not modify this certification.":"自动更新已启用,请勿修改此证书配置。","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Certification":"证书","Change Certificate":"更改证书","Comments":"注释","Config Templates":"配置","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Custom":"自定义","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Description":"描述","Development Mode":"开发模式","Dir":"目录","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Domain":"域名","Domain Config Created Successfully":"域名配置文件创建成功","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","File":"文件","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Format Code":"代码格式化","Format error %{msg}":"保存错误 %{msg}","Format successfully":"保存成功","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","HTTP Challenge Port":"HTTP Challenge 监听端口","HTTP Port":"HTTP 监听端口","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Jwt Secret":"Jwt 密钥","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Multi-line Directive":"单行指令","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","Next":"下一步","Nginx Access Log Path":"Nginx 访问日志路径","Nginx Error Log Path":"Nginx 错误日志路径","Nginx Log":"Nginx 日志","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note":"注意","Obtaining certificate":"正在获取证书","OK":"确定","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reloading nginx":"正在重载 Nginx","Reset":"重置","Run Mode":"运行模式","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","SSL Certificate Key Path":"SSL证书密钥路径","SSL Certificate Path":"SSL证书路径","SSL Certification Content":"SSL证书内容","SSL Certification Key Content":"SSL证书密钥内容","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","Table":"列表","Terminal":"终端","Terminal Start Command":"终端启动命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The server_name in the current configuration must be the domain name you need to get the certificate.":"当前配置中的 server_name 必须为需要申请证书的域名。","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Type":"类型","Updated at":"修改时间","Updated successfully":"更新成功","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","View":"查看","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","License":{"Project":"开源许可"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}},"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Auto":"自動","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Comments":"註釋","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Development Mode":"開發模式","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Domain Config Created Successfully":"域名配置文件創建成功","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error Logs":"錯誤日志","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","Next":"下一步","Nginx Log":"Nginx 日誌","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Obtaining certificate":"正在獲取證書,請稍等...","OK":"確定","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reloading nginx":"重载 Nginx","Reset":"重設","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","Table":"表格","Terminal":"終端","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Updated at":"修改時間","Updated successfully":"已成功更新","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","License":{"Project":"開源軟體授權條款"}}} \ No newline at end of file diff --git a/frontend/src/language/zh_CN/app.mo b/frontend/src/language/zh_CN/app.mo index 18dccbb79b75e82616fc6345027d8930c664f888..b158d7bc2c6cda7951236e4f1a23c92d184f7f33 100644 GIT binary patch delta 4197 zcmZA3d6dpo9LMoHW?@8Q#xnMqEYDc7G{}&BPxf6H8OCnxGEDu5#$I+Z*6bn6Gxqfl zBvNrGBpuF?qnsoiDWv!3dA?4LdwibPz4!O~-QT_U_j{gkzVpT|-nE#pMUHZW6eoEi zoC^tY?(s|NrQ~xi970fCIgwLbehkH;m>)}G9!$hsSl`+$FrId2tb*gPGHyV|@!Ul! zVRT%@NW6|3=vS!isPjGK6gLBN<1*Cs>#e=ZJdC>T6lwuyF^2oQ z3shq1xP=AqDdxojF*?DyQhaDdHBdLIXZ>yQW!fpI^G9M%^sIjxYC?;#4z5An_!?>= zH!+g?yI-jI@J~CT82hOkmBJ!e4Yl>Ht-m{J>j$HDAPse+@tA;9P!ryQ1u+{nvD2st zoX1jl89fc~m(C2!Zfv&)lnBTMy;SFYULe~IlA8FXgfX)^)k&xt^BARzlB=JBh>ie zg@O~#jojPC;A@yri2aYF(wz>?JRP;=Q&DgIO4P*Gp(f-<4SdLspF};XuaMWq{fM*i zF6z1rmaCU>mbnzQ!1bsd-|AV%QPkF+M9uI5YUa05Tm2jAf(OW=TqOIeb{y)wL{xuG z)b*`V6HUP!IMmw1Q435*UFR*Z6PBW0sw~t%t57rDjavC3)JjgEE zYA4HM39OEKG#yay$OMeS707s=+eSrOeE_x6W2h}Xg*x%F9lwp5$X(=K?jdTW(M5w3 z@u6lV4k6Pgq)DGoh z`I>kXYUg56<5WT|ED<$+67pKOhByPeVQqc?Z%|3a68!#_#VM!@H=_pHj=EtsYQ;xU zH@tuv_$q3mH&HM1AE@hM*bbc+i<)R0CZG?wrE7y;;D>}tX*$wSKeh8Q2Y&;yQ5Wtl z8N9&}RQrs19<}1js7G}dHIb)g9%iFQRRlF|B9_5UsBzNcc>bzPqC*!>GZ*6PwAY|6 zyk!1^I=^^)@chzdRkNb?lq;N6Wg1~s1*${$DszEY{%E4 z2HIimy{MP!xV7(~-ig0a=SA^i>8HDpSpoG<)I*MYt}7L7S#q$$rI}-`KLa(uY}7iKnL&(^K0wB zXx=dIq9*hhwWSfhpmC^il2GF`McuF!YJokie-wHVbfi-W#Yw1%OhxrCF;}8?XuY*} zpl-O={1&zKw^26^=Y>!^2CHFZ)cGl>;}gy42|Rz@co7{D_z7wPt4+W4pF~}F7PW#a zs1^Ngx^lt(e5i4JsPikCwNdX-b8Gi72bN?1wS{Bp(1jjq;7oI|ow&jDo5xV+pEWO_ zCiVk{;XUhrU_L=DEUdh9BQO@3yPNJ&X+~uSYK#6t4VFJ%%&Vl!*E z!+6@s7+8pziQ3^gsBg(U)T8m+aqk-{n#p&_B;CIlf*Z&J@*z=4BK%zml*W8&5dE^% zBN~`_2a0}F{8ktGv3XYBr!t4=kJwaFN8kVFOB))8NfqKFyNHUmRAms+-}F?{iR>i$ zJ28Q%yiGm`)OeRr3(B(g$M_zZOWq>$$XMN9+o>{)=n<&23gX7#KGK~`A-&0PqQB$s zkaVIln&{_xIaxxQlAc8GL~D{kR8mMYGKs7r6}A4sWEKf014ukkSwZydR1O6Rd@kg( zCE-a0{>P)v9{QkcAsqrW{@090NF%b0nmwyY+(h!&&rE-6LUlF!LXGL-ZuGsr+Pn@~JAIaqP~u?fjfCX&y{IHJ;z zY$uh;L87uTi0g&?r`Qc4MaU?kqQ9ali%D}*m*gf}iAr^{LsM=?Wepig4iJ@3gScsC z7fi7Fi`1s0EXlS5eP1}C678jACdnlF9au+H0>A&NBocj}Tae8}r4MNssQv#DO|=`@ zL|!FtlJR5@sY#xd`Bc(KXX_}9aaM1O^~nfQLVaEJ@m$$Uy$o68KN0225k0U^+JMyf z#;K#m4C+6qZ=W%#{@c-gBmDltGeZ}2D4gQ2RlI6gcvkk$3-|l`#2*Xy5B4R6E-2$` K;a^+6O2~inwSN-; delta 4094 zcmYk<3v|wP9LMpWU0t%dEL)*HV;dIJOv`FfvfA9DP~SHe{eJ(;@Am&a&uY_%qr(GVw~DB8 z9D7MSaw*cezpQFsEw@f5bk@9`SEh>bD2g;#HZKI-kUJNCwO zoQbp(aIaE`;KT-Of;Fgyg4i1mU=m(NA11Z*?(d7b{~qL$8;VVF0_yoftNYCbsD75C zCQyZ~=-;iO5YLHi7>9?jIX0kX@)N3qbJz+a_=v%H)P1QKjXmvr4r(9+Fb7AVI;=zu zU=?cMYcZAnU5(xF396&xcpaWWEqNI0tMf6aB~L^(&=J*9H|&JHPy-&1*WxtPzyhcN zlwb!eM?JqC1N7nc*olwLFHsGj!c_bfHPbkjM-6sBtyCHxYOoK6mL3zR7os{`X!WJ2 z72b#`xDT}w-^Q{2TFM_ep$Gm#&EPU>=8c&KeY-fbGwON{Y7^z6W?p31*Pv!ri|XJ# z)PVORO}ayvfeo05F>P3XjXb@Lx8&KV-F`o6U?Wi-PDM35+pf<=y^>;NTeu2bf*VlJ zWiVZB!aK}Cs0ofjt$2aeivkq1v~y7-EJKa_HPp!0qaN6T4BG9p`sb+oez5bupq>w7 z{WZ{d48tU=C!_XMI?lj6yB^p{L7VDbR0n%dBmERL^Dj{|If?4C?rbX4(z8 z#q~vXI2tuTKk5|(P_L%keBIoETG98hvA+MuDd@p(P@C>M)Chk^4d`FglEyMk&G0(Z z3MHckej{q-GEwd1qxR5X)CvwmwuKvmWmtr_;=h=p?|(MGyLw<8s)0$Uj;5n#`UI+@ zMW_ZVPy<|z+Qo08o~uXQ_YrDBhKER$Zf4?AKq2K3XKM`#yWSkNa@V6)Bn9<+8tVBB)VuGEn!r$Bz`LP<6S{G#`6%jvIaZ&K zYIu>=t56NBLEX0%^~16owO4*dwRhg?moSBT6tmO$uBg40sr6@nxqfzG9IC;|R)5^| zo5jdKS8DamsQb60I^JjJ>yg!WM^KykEb6|CW;EYPO(+m&g+%086a5vb66jTE@qXv-g-QY%`HqjW= z0G~(g<_)Ot_W@LcN6oKL&wqpbbHDPTcixglG~;B{z`J9VzW=!t^b!)Bq|vvHmJl+l4yRgZoi4_z*RtQ|2Fb zKCH9XPy*`yM6)Yu4`o|@kU0vqf>Tffn2l=psm`pw3Z-`AO0(MBfqG!S`2lKRA7KQZ zw)1Dq-%u0!6K7$QF5b7sk6M{^sP^`l2Llu|gTv-A)Mh-5P4IWC|BXKCP13vu(##Ch z()L1qJ91F3XsliLBa7yWkukX%Y=rBHj=+7lpeP$ z`q3>XLx}#UW)tmz$%G|y+sKt;h7~H2_wIU-+sNzW6{4djxsmiD`u$u+mJ=NnWP={< zNP)kpp%(<9|F6*^ZzcLql9$N{qGL6AjO-z!$kRlB>U8Y&aKrFUl1p~kxoW(ZyhElD z{xpY*E!|Dz4l;qXC0$7w(eWl3OYT#JV~0m*n-^1_LZ*`Eh`viYW|11QM3t+K zfmfAPj3e0#_;^4yJ38ZhE4Rc|R=&bI3MIrJ+CBM{W|ADD<9;%d^db7@Z6wc=-ef6> zCpyB&8)P17Lv#em+oT0~io8lnNeoFQgUA+=Mw*f*v@dR_kWOwU3&~yNVKSWDO|Cww zsQB!}N_>R8LCertificate Status + + +import {useGettext} from 'vue3-gettext' +import {ref} from 'vue' + +const {$gettext} = useGettext() + +const props = defineProps(['directivesMap']) + +const visible = ref(false) + +function open() { + visible.value = true +} + + + + + diff --git a/frontend/src/views/domain/cert/IssueCert.vue b/frontend/src/views/domain/cert/IssueCert.vue index 503449f3b..285ba15b4 100644 --- a/frontend/src/views/domain/cert/IssueCert.vue +++ b/frontend/src/views/domain/cert/IssueCert.vue @@ -4,6 +4,7 @@ import {computed, h, nextTick, onMounted, ref, VNode, watch} from 'vue' import {message} from 'ant-design-vue' import domain from '@/api/domain' import websocket from '@/lib/websocket' +import Template from '@/views/template/Template.vue' const {$gettext, interpolate} = useGettext() @@ -56,8 +57,6 @@ function job() { function callback(ssl_certificate: string, ssl_certificate_key: string) { props.directivesMap['ssl_certificate'][0]['params'] = ssl_certificate props.directivesMap['ssl_certificate_key'][0]['params'] = ssl_certificate_key - - emit('callback') } function change_auto_cert(r: boolean) { @@ -178,7 +177,7 @@ const modalClosable = ref(false) -
+
-

- Note: The server_name in the current configuration must be the domain name - you need to get the certificate. -

-

- The certificate for the domain will be checked every hour, - and will be renewed if it has been more than 1 month since it was last issued. -

-

- Make sure you have configured a reverse proxy for .well-known - directory to HTTPChallengePort (default: 9180) before getting the certificate. -

+ + +
@@ -231,6 +234,10 @@ const modalClosable = ref(false)