diff --git a/.air.toml b/.air.toml index a9855a67f..0d1e7033f 100644 --- a/.air.toml +++ b/.air.toml @@ -13,7 +13,7 @@ bin = "tmp/main" # Customize binary. full_bin = "APP_ENV=dev APP_USER=air ./tmp/main" # Watch these filename extensions. -include_ext = ["go", "tpl", "tmpl", "html"] +include_ext = ["go", "tpl", "tmpl", "html", "conf"] # Ignore these filename extensions or directories. exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules", "upload"] # Watch these directories if you specified. diff --git a/README-zh_CN.md b/README-zh_CN.md index 5fbb2c7ef..850b9a3f6 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -91,12 +91,16 @@ Nginx 网络管理界面,由 [0xJacky](https://jackyu.cn/) 与 [Hintay](https 我们欢迎您将项目翻译成任何语言。 ### 构建基于 - -- [The Go Programming Language](https://go.dev/) +- [The Go Programming Language](https://go.dev) - [Gin Web Framework](https://gin-gonic.com) -- [GORM](http://gorm.io/index.html) -- [Vue 2](https://vuejs.org) -- [vue-gettext](https://github.com/Polyconseil/vue-gettext) +- [GORM](http://gorm.io) +- [Vue 3](https://v3.vuejs.org) +- [Vite](https://vitejs.dev) +- [TypeScript](https://www.typescriptlang.org/) +- [Ant Design Vue](https://antdv.com) +- [vue3-gettext](https://github.com/jshmrtn/vue3-gettext) +- [vue3-ace-editor](https://github.com/CarterLi/vue3-ace-editor) +- [Gonginx](https://github.com/tufanbarisyildirim/gonginx) ## 入门指南 diff --git a/README-zh_TW.md b/README-zh_TW.md index 79cfc1a91..b9f7c54a6 100644 --- a/README-zh_TW.md +++ b/README-zh_TW.md @@ -93,12 +93,16 @@ Nginx 網路管理介面,由 [0xJacky](https://jackyu.cn/) 與 [Hintay](https 我們歡迎您將專案翻譯成任何語言。 ### 構建基於 - -- [The Go Programming Language](https://go.dev/) +- [The Go Programming Language](https://go.dev) - [Gin Web Framework](https://gin-gonic.com) -- [GORM](http://gorm.io/index.html) -- [Vue 2](https://vuejs.org) -- [vue-gettext](https://github.com/Polyconseil/vue-gettext) +- [GORM](http://gorm.io) +- [Vue 3](https://v3.vuejs.org) +- [Vite](https://vitejs.dev) +- [TypeScript](https://www.typescriptlang.org/) +- [Ant Design Vue](https://antdv.com) +- [vue3-gettext](https://github.com/jshmrtn/vue3-gettext) +- [vue3-ace-editor](https://github.com/CarterLi/vue3-ace-editor) +- [Gonginx](https://github.com/tufanbarisyildirim/gonginx) ## 入門指南 diff --git a/README.md b/README.md index 02040d441..ca6e08f77 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ We welcome translations into any language. - [Ant Design Vue](https://antdv.com) - [vue3-gettext](https://github.com/jshmrtn/vue3-gettext) - [vue3-ace-editor](https://github.com/CarterLi/vue3-ace-editor) +- [Gonginx](https://github.com/tufanbarisyildirim/gonginx) ## Getting Started diff --git a/frontend/components.d.ts b/frontend/components.d.ts index da24afcaa..87cc8d6dc 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -27,6 +27,8 @@ declare module '@vue/runtime-core' { ALayoutFooter: typeof import('ant-design-vue/es')['LayoutFooter'] ALayoutHeader: typeof import('ant-design-vue/es')['LayoutHeader'] ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider'] + AList: typeof import('ant-design-vue/es')['List'] + AListItem: typeof import('ant-design-vue/es')['ListItem'] AMenu: typeof import('ant-design-vue/es')['Menu'] AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] AModal: typeof import('ant-design-vue/es')['Modal'] @@ -65,8 +67,5 @@ declare module '@vue/runtime-core' { StdDataEntryComponentsStdPassword: typeof import('./src/components/StdDataEntry/components/StdPassword.vue')['default'] StdDataEntryComponentsStdSelect: typeof import('./src/components/StdDataEntry/components/StdSelect.vue')['default'] StdDataEntryComponentsStdSelector: typeof import('./src/components/StdDataEntry/components/StdSelector.vue')['default'] - StdDataEntryCompontentsStdPassword: typeof import('./src/components/StdDataEntry/compontents/StdPassword.vue')['default'] - StdDataEntryCompontentsStdSelect: typeof import('./src/components/StdDataEntry/compontents/StdSelect.vue')['default'] - StdDataEntryCompontentsStdSelector: typeof import('./src/components/StdDataEntry/compontents/StdSelector.vue')['default'] } } diff --git a/frontend/package.json b/frontend/package.json index 12b212053..e6f5f6978 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", @@ -39,7 +39,7 @@ "less": "^4.1.3", "typescript": "^4.6.4", "unplugin-vue-components": "^0.22.9", - "vite": "^3.2.3", + "vite": "^4.0.3", "vite-plugin-html": "^3.2.0", "vue-tsc": "^1.0.9" } 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/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/api/ngx.ts b/frontend/src/api/ngx.ts index 8ed205975..62fb41e75 100644 --- a/frontend/src/api/ngx.ts +++ b/frontend/src/api/ngx.ts @@ -7,6 +7,10 @@ const ngx = { tokenize_config(content: string) { return http.post('/ngx/tokenize_config', {content}) + }, + + format_code(content: string) { + return http.post('/ngx/format_code', {content}) } } 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/api/template.ts b/frontend/src/api/template.ts new file mode 100644 index 000000000..d15057a60 --- /dev/null +++ b/frontend/src/api/template.ts @@ -0,0 +1,25 @@ +import Curd from '@/api/curd' +import http from '@/lib/http' + +class Template extends Curd { + get_config_list() { + return http.get('template/configs') + } + + get_block_list() { + return http.get('template/blocks') + } + + get_config(name: string) { + return http.get('template/config/' + name) + } + + get_block(name: string) { + return http.get('template/block/' + name) + } + +} + +const template = new Template('/template') + +export default template 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/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/StdPassword.vue b/frontend/src/components/StdDataEntry/compontents/StdPassword.vue deleted file mode 100644 index d7cede50a..000000000 --- a/frontend/src/components/StdDataEntry/compontents/StdPassword.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - - - \ 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 8625995b9..000000000 --- a/frontend/src/components/StdDataEntry/compontents/StdSelector.vue +++ /dev/null @@ -1,137 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend/src/language/en/app.po b/frontend/src/language/en/app.po index 00f363a7c..7ff0cd3ef 100644 --- a/frontend/src/language/en/app.po +++ b/frontend/src/language/en/app.po @@ -9,21 +9,22 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: src/routes/index.ts:116 +#: src/routes/index.ts:134 msgid "About" msgstr "About" -#: src/routes/index.ts:99 src/views/domain/ngx_conf/LogEntry.vue:64 +#: src/routes/index.ts:109 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/user/User.vue:43 +#: 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" -#: src/components/StdDataDisplay/StdCurd.vue:134 -#: src/components/StdDataDisplay/StdCurd.vue:26 +#: src/components/StdDataDisplay/StdCurd.vue:145 +#: src/components/StdDataDisplay/StdCurd.vue:25 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:26 msgid "Add" msgstr "" @@ -33,47 +34,75 @@ 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:57 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/DirectiveEditorItem.vue:20 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/domain/ngx_conf/ConfigTemplate.vue:11 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:12 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:15 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:19 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:20 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:23 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:29 +msgid "Author" +msgstr "" + +#: src/views/preference/Preference.vue:22 +#: src/views/preference/Preference.vue:23 +msgid "Auto" +msgstr "" + +#: 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 "" -#: src/views/domain/cert/IssueCert.vue:78 +#: 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:72 +#: src/views/domain/cert/IssueCert.vue:65 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/config/Config.vue:16 src/views/config/Config.vue:17 +#: src/views/config/Config.vue:27 src/views/config/Config.vue:5 +#: src/views/config/ConfigEdit.vue:64 src/views/domain/DomainEdit.vue:187 +#: src/views/nginx_log/NginxLog.vue:173 msgid "Back" msgstr "Back" @@ -86,40 +115,65 @@ 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/StdDataEntry/compontents/StdSelector.vue:11 -#: src/views/config/ConfigEdit.vue:49 +#: src/components/StdDataDisplay/StdBatchEdit.vue:7 +#: src/components/StdDataDisplay/StdCurd.vue:27 +#: src/components/StdDataEntry/components/StdSelector.vue:11 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:35 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/NgxConfigEditor.vue:175 +#: src/routes/index.ts:87 src/views/cert/Cert.vue:2 +#, fuzzy +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 +#: src/views/domain/ngx_conf/NgxConfigEditor.vue:180 msgid "Comments" msgstr "Comments" -#: src/views/domain/DomainAdd.vue:12 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:61 +#, fuzzy +msgid "Config Templates" +msgstr "Configurations" + +#: src/views/domain/DomainAdd.vue:11 msgid "Configuration Name" msgstr "Configuration Name" @@ -131,8 +185,9 @@ 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/directive/DirectiveEditorItem.vue:37 +#: src/views/domain/ngx_conf/LocationEditor.vue:37 +#: src/views/domain/ngx_conf/LocationEditor.vue:53 msgid "Content" msgstr "Content" @@ -144,7 +199,7 @@ msgstr "CPU Status" msgid "CPU:" msgstr "CPU:" -#: src/views/domain/DomainAdd.vue:150 +#: src/views/domain/DomainAdd.vue:149 msgid "Create Another" msgstr "Create Another" @@ -156,7 +211,21 @@ msgstr "Created at" msgid "Creating client facilitates communication with the CA server" msgstr "" -#: src/routes/index.ts:27 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:22 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:23 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:26 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:32 +#: src/views/domain/ngx_conf/NgxConfigEditor.vue:6 +#: src/views/domain/ngx_conf/NgxConfigEditor.vue:7 +msgid "Custom" +msgstr "" + +#: src/views/preference/Preference.vue:28 +#: src/views/preference/Preference.vue:29 +msgid "Dark" +msgstr "" + +#: src/routes/index.ts:29 msgid "Dashboard" msgstr "Dashboard" @@ -164,41 +233,58 @@ 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 "" +#: src/views/domain/ngx_conf/ConfigTemplate.vue:12 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:13 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:16 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:20 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:21 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:24 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:30 +msgid "Description" +msgstr "" + #: src/views/other/About.vue:7 src/views/other/About.vue:8 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" +#: 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:73 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/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 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" @@ -206,19 +292,23 @@ msgstr "Disabled successfully" msgid "Disk IO" msgstr "Disk IO" -#: src/views/domain/DomainAdd.vue:60 +#: src/views/cert/Cert.vue:32 +msgid "Domain" +msgstr "" + +#: src/views/domain/DomainAdd.vue:58 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:79 src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "Edit Configuration" -#: src/routes/index.ts:59 +#: src/routes/index.ts:61 msgid "Edit Site" msgstr "Edit Site" @@ -226,11 +316,11 @@ msgstr "Edit Site" msgid "Email (*)" msgstr "Email (*)" -#: src/views/domain/cert/IssueCert.vue:74 +#: src/views/domain/cert/IssueCert.vue:67 msgid "Enable auto-renewal failed for %{name}" msgstr "Enable auto-renewal failed for %{name}" -#: src/views/domain/DomainAdd.vue:50 +#: src/views/domain/DomainAdd.vue:51 msgid "Enable failed" msgstr "Enable failed" @@ -238,39 +328,43 @@ 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/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 +#: 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:47 src/views/domain/DomainEdit.vue:109 +#: src/views/domain/DomainList.vue:59 msgid "Enabled successfully" msgstr "Enabled successfully" -#: src/views/domain/cert/IssueCert.vue:17 +#: src/views/domain/cert/IssueCert.vue:18 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:113 src/views/domain/ngx_conf/LogEntry.vue:68 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}" #: 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}" @@ -278,6 +372,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" @@ -290,7 +388,21 @@ msgstr "" msgid "Finished" msgstr "Finished" -#: src/components/StdDataEntry/compontents/StdPassword.vue:42 +#: src/views/config/ConfigEdit.vue:67 +msgid "Format Code" +msgstr "" + +#: src/views/config/ConfigEdit.vue:52 +#, fuzzy +msgid "Format error %{msg}" +msgstr "Save error %{msg}" + +#: src/views/config/ConfigEdit.vue:50 +#, fuzzy +msgid "Format successfully" +msgstr "Saved successfully" + +#: src/components/StdDataEntry/components/StdPassword.vue:42 msgid "Generate" msgstr "" @@ -298,15 +410,23 @@ msgstr "" msgid "Generating private key for registering account" msgstr "" -#: src/views/domain/cert/IssueCert.vue:103 +#: src/views/domain/cert/IssueCert.vue:96 msgid "Getting the certificate, please wait..." msgstr "Getting the certificate, please wait..." -#: src/routes/index.ts:20 +#: src/routes/index.ts:22 msgid "Home" msgstr "Home" -#: src/routes/index.ts:126 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:144 src/views/other/Install.vue:128 msgid "Install" msgstr "Install" @@ -315,7 +435,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}" @@ -324,23 +444,34 @@ 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:25 +#: src/views/preference/Preference.vue:26 +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:150 src/views/other/Login.vue:103 msgid "Login" msgstr "Login" @@ -352,7 +483,7 @@ msgstr "Login successful" msgid "Logout successful" msgstr "Logout successful" -#: src/views/domain/cert/IssueCert.vue:226 +#: 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." @@ -360,15 +491,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:70 msgid "Manage Configs" msgstr "Manage Configs" -#: src/routes/index.ts:43 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:35 src/views/user/User.vue:2 +#: src/routes/index.ts:37 src/views/user/User.vue:2 msgid "Manage Users" msgstr "Manage Users" @@ -380,21 +511,28 @@ 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" -#: src/views/domain/DomainAdd.vue:147 +#: src/views/domain/DomainAdd.vue:146 msgid "Modify Config" msgstr "Modify Config" -#: src/views/config/Config.vue:12 src/views/domain/DomainList.vue:14 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:10 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:9 +#, fuzzy +msgid "Multi-line Directive" +msgstr "Single Directive" + +#: 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" @@ -414,45 +552,50 @@ msgstr "Network Total Receive" msgid "Network Total Send" msgstr "Network Total Send" -#: src/views/domain/DomainAdd.vue:137 +#: src/views/domain/DomainAdd.vue:136 msgid "Next" msgstr "Next" -#: src/routes/index.ts:93 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:103 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/DirectiveEditorItem.vue:22 +#: 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:156 src/routes/index.ts:158 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}" -#: src/views/domain/cert/IssueCert.vue:218 -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" msgstr "" -#: src/components/StdDataDisplay/StdCurd.vue:29 -#: src/components/StdDataDisplay/StdTable.vue:43 -#: src/components/StdDataEntry/compontents/StdSelector.vue:12 -#: src/views/domain/DomainList.vue:26 +#: 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/views/domain/DomainList.vue:25 msgid "OK" msgstr "" @@ -472,8 +615,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 +632,10 @@ msgstr "Please input your password!" msgid "Please input your username!" msgstr "Please input your username!" +#: src/routes/index.ts:126 src/views/preference/Preference.vue:2 +msgid "Preference" +msgstr "" + #: src/language/constants.ts:12 #, fuzzy msgid "Preparing lego configurations" @@ -522,35 +669,56 @@ 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/preference/Preference.vue:8 +#, fuzzy +msgid "Run Mode" +msgstr "Advance Mode" + +#: src/views/config/ConfigEdit.vue:70 src/views/domain/DomainEdit.vue:190 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:33 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:34 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:41 +#: src/views/preference/Preference.vue:43 +#: src/views/preference/Preference.vue:44 msgid "Save" msgstr "Save" -#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32 -#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:33 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:34 #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:35 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:36 msgid "Save Directive" msgstr "Save Directive" -#: src/views/config/ConfigEdit.vue:36 src/views/domain/DomainAdd.vue:54 +#: src/views/config/ConfigEdit.vue:43 src/views/domain/DomainAdd.vue:55 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37 msgid "Save error %{msg}" msgstr "Save error %{msg}" -#: src/components/StdDataDisplay/StdCurd.vue:102 +#: src/components/StdDataDisplay/StdBatchEdit.vue:40 +#: src/views/preference/Preference.vue:39 +#, 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/config/ConfigEdit.vue:41 src/views/domain/DomainAdd.vue:44 +#: src/views/domain/DomainEdit.vue:97 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:35 msgid "Saved successfully" msgstr "Saved successfully" -#: src/components/StdDataEntry/compontents/StdSelector.vue:13 +#: src/components/StdDataEntry/components/StdSelector.vue:13 msgid "Selector" msgstr "" @@ -558,12 +726,14 @@ 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/views/other/Install.vue:71 +#: 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:29 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 "Server error" @@ -571,33 +741,49 @@ 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:209 src/views/domain/DomainAdd.vue:112 +#: 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" -#: 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:117 #, fuzzy msgid "Site Logs" msgstr "Sites List" -#: src/routes/index.ts:51 +#: src/routes/index.ts:53 msgid "Sites List" msgstr "Sites List" -#: src/views/domain/DomainList.vue:19 +#: src/views/cert/Cert.vue:65 +#, fuzzy +msgid "SSL Certificate Key Path" +msgstr "Certificate Status" + +#: 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" @@ -605,7 +791,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}" @@ -618,11 +804,15 @@ msgstr "Swap" msgid "Table" msgstr "Enabled" -#: src/routes/index.ts:85 src/views/pty/Terminal.vue:2 +#: src/routes/index.ts:95 src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "Terminal" -#: src/views/domain/cert/IssueCert.vue:222 +#: src/views/preference/Preference.vue:14 +msgid "Terminal Start Command" +msgstr "" + +#: 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." @@ -634,15 +824,37 @@ 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 "" -#: src/views/config/Config.vue:17 src/views/domain/DomainList.vue:36 -#: src/views/user/User.vue:37 +#: src/views/preference/Preference.vue:20 +msgid "Theme" +msgstr "" + +#: src/views/config/config.ts:14 +msgid "Type" +msgstr "" + +#: 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" +#: src/components/StdDataDisplay/StdTable.vue:461 +#, fuzzy +msgid "Updated successfully" +msgstr "Saved successfully" + #: src/views/dashboard/DashBoard.vue:137 msgid "Uptime:" msgstr "Uptime:" @@ -659,7 +871,13 @@ msgstr "Username (*)" msgid "Using HTTP01 challenge provider" msgstr "" -#: src/views/domain/cert/IssueCert.vue:26 src/views/domain/DomainAdd.vue:24 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:10 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:13 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:9 +msgid "View" +msgstr "" + +#: src/views/domain/cert/IssueCert.vue:27 src/views/domain/DomainAdd.vue:22 msgid "Warning" msgstr "Warning" @@ -676,8 +894,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/DirectiveEditorItem.vue:21 +#: src/views/domain/ngx_conf/LocationEditor.vue:20 msgid "Yes" msgstr "Yes" @@ -686,6 +904,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..0dbed548a 100644 --- a/frontend/src/language/messages.pot +++ b/frontend/src/language/messages.pot @@ -2,23 +2,25 @@ msgid "" msgstr "" "Content-Type: text/plain; charset=UTF-8\n" -#: src/routes/index.ts:116 +#: src/routes/index.ts:134 msgid "About" msgstr "" -#: src/routes/index.ts:99 +#: src/routes/index.ts:109 #: 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/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 "" -#: src/components/StdDataDisplay/StdCurd.vue:134 -#: src/components/StdDataDisplay/StdCurd.vue:26 +#: src/components/StdDataDisplay/StdCurd.vue:145 +#: src/components/StdDataDisplay/StdCurd.vue:25 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:26 msgid "Add" msgstr "" @@ -28,47 +30,78 @@ 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:57 #: 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/DirectiveEditorItem.vue:20 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/domain/ngx_conf/ConfigTemplate.vue:11 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:12 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:15 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:19 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:20 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:23 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:29 +msgid "Author" +msgstr "" + +#: src/views/preference/Preference.vue:22 +#: src/views/preference/Preference.vue:23 +msgid "Auto" +msgstr "" + +#: 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 "" -#: src/views/domain/cert/IssueCert.vue:78 +#: src/views/domain/cert/IssueCert.vue:71 msgid "Auto-renewal disabled for %{name}" msgstr "" -#: src/views/domain/cert/IssueCert.vue:72 +#: src/views/domain/cert/IssueCert.vue:65 msgid "Auto-renewal enabled for %{name}" msgstr "" -#: src/views/domain/DomainEdit.vue:178 -#: src/views/nginx_log/NginxLog.vue:172 +#: src/views/config/Config.vue:16 +#: src/views/config/Config.vue:17 +#: src/views/config/Config.vue:27 +#: src/views/config/Config.vue:5 +#: src/views/config/ConfigEdit.vue:64 +#: src/views/domain/DomainEdit.vue:187 +#: src/views/nginx_log/NginxLog.vue:173 msgid "Back" msgstr "" @@ -80,40 +113,64 @@ 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/StdDataEntry/compontents/StdSelector.vue:11 -#: src/views/config/ConfigEdit.vue:49 +#: src/components/StdDataDisplay/StdBatchEdit.vue:7 +#: src/components/StdDataDisplay/StdCurd.vue:27 +#: src/components/StdDataEntry/components/StdSelector.vue:11 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:35 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/NgxConfigEditor.vue:175 +#: src/routes/index.ts:87 +#: src/views/cert/Cert.vue:2 +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 +#: src/views/domain/ngx_conf/NgxConfigEditor.vue:180 msgid "Comments" msgstr "" -#: src/views/domain/DomainAdd.vue:12 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:61 +msgid "Config Templates" +msgstr "" + +#: src/views/domain/DomainAdd.vue:11 msgid "Configuration Name" msgstr "" @@ -125,8 +182,9 @@ 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/directive/DirectiveEditorItem.vue:37 +#: src/views/domain/ngx_conf/LocationEditor.vue:37 +#: src/views/domain/ngx_conf/LocationEditor.vue:53 msgid "Content" msgstr "" @@ -138,7 +196,7 @@ msgstr "" msgid "CPU:" msgstr "" -#: src/views/domain/DomainAdd.vue:150 +#: src/views/domain/DomainAdd.vue:149 msgid "Create Another" msgstr "" @@ -150,7 +208,21 @@ msgstr "" msgid "Creating client facilitates communication with the CA server" msgstr "" -#: src/routes/index.ts:27 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:22 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:23 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:26 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:32 +#: src/views/domain/ngx_conf/NgxConfigEditor.vue:6 +#: src/views/domain/ngx_conf/NgxConfigEditor.vue:7 +msgid "Custom" +msgstr "" + +#: src/views/preference/Preference.vue:28 +#: src/views/preference/Preference.vue:29 +msgid "Dark" +msgstr "" + +#: src/routes/index.ts:29 msgid "Dashboard" msgstr "" @@ -158,44 +230,64 @@ 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 "" +#: src/views/domain/ngx_conf/ConfigTemplate.vue:12 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:13 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:16 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:20 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:21 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:24 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:30 +msgid "Description" +msgstr "" + #: src/views/other/About.vue:7 #: src/views/other/About.vue:8 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 "" +#: 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:73 msgid "Disable auto-renewal failed for %{name}" msgstr "" +#: src/views/cert/Cert.vue:51 #: 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 "" @@ -203,20 +295,25 @@ msgstr "" msgid "Disk IO" msgstr "" -#: src/views/domain/DomainAdd.vue:60 +#: src/views/cert/Cert.vue:32 +msgid "Domain" +msgstr "" + +#: src/views/domain/DomainAdd.vue:58 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:79 #: src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "" -#: src/routes/index.ts:59 +#: src/routes/index.ts:61 msgid "Edit Site" msgstr "" @@ -224,11 +321,11 @@ msgstr "" msgid "Email (*)" msgstr "" -#: src/views/domain/cert/IssueCert.vue:74 +#: src/views/domain/cert/IssueCert.vue:67 msgid "Enable auto-renewal failed for %{name}" msgstr "" -#: src/views/domain/DomainAdd.vue:50 +#: src/views/domain/DomainAdd.vue:51 msgid "Enable failed" msgstr "" @@ -236,45 +333,51 @@ msgstr "" msgid "Enable TLS" msgstr "" +#: 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: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/DomainAdd.vue:47 +#: src/views/domain/DomainEdit.vue:109 +#: src/views/domain/DomainList.vue:59 msgid "Enabled successfully" msgstr "" -#: src/views/domain/cert/IssueCert.vue:17 +#: src/views/domain/cert/IssueCert.vue:18 msgid "Encrypt website with Let's Encrypt" msgstr "" -#: src/routes/index.ts:103 +#: src/routes/index.ts:113 #: src/views/domain/ngx_conf/LogEntry.vue:68 msgid "Error Logs" msgstr "" -#: src/views/domain/cert/CertInfo.vue:17 +#: src/views/domain/cert/CertInfo.vue:12 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 "" @@ -282,6 +385,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" @@ -296,7 +403,19 @@ msgstr "" msgid "Finished" msgstr "" -#: src/components/StdDataEntry/compontents/StdPassword.vue:42 +#: src/views/config/ConfigEdit.vue:67 +msgid "Format Code" +msgstr "" + +#: src/views/config/ConfigEdit.vue:52 +msgid "Format error %{msg}" +msgstr "" + +#: src/views/config/ConfigEdit.vue:50 +msgid "Format successfully" +msgstr "" + +#: src/components/StdDataEntry/components/StdPassword.vue:42 msgid "Generate" msgstr "" @@ -304,15 +423,23 @@ msgstr "" msgid "Generating private key for registering account" msgstr "" -#: src/views/domain/cert/IssueCert.vue:103 +#: src/views/domain/cert/IssueCert.vue:96 msgid "Getting the certificate, please wait..." msgstr "" -#: src/routes/index.ts:20 +#: src/routes/index.ts:22 msgid "Home" msgstr "" -#: src/routes/index.ts:126 +#: 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:144 #: src/views/other/Install.vue:128 msgid "Install" msgstr "" @@ -321,7 +448,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 "" @@ -329,23 +456,34 @@ 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:25 +#: src/views/preference/Preference.vue:26 +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:150 #: src/views/other/Login.vue:103 msgid "Login" msgstr "" @@ -358,20 +496,20 @@ msgstr "" msgid "Logout successful" msgstr "" -#: src/views/domain/cert/IssueCert.vue:226 +#: 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 "" -#: src/routes/index.ts:68 +#: src/routes/index.ts:70 msgid "Manage Configs" msgstr "" -#: src/routes/index.ts:43 +#: src/routes/index.ts:45 #: src/views/domain/DomainList.vue:2 msgid "Manage Sites" msgstr "" -#: src/routes/index.ts:35 +#: src/routes/index.ts:37 #: src/views/user/User.vue:2 msgid "Manage Users" msgstr "" @@ -384,21 +522,28 @@ 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 "" -#: src/views/domain/DomainAdd.vue:147 +#: src/views/domain/DomainAdd.vue:146 msgid "Modify Config" msgstr "" -#: src/views/config/Config.vue:12 -#: src/views/domain/DomainList.vue:14 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:10 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:9 +msgid "Multi-line Directive" +msgstr "" + +#: 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 "" @@ -418,33 +563,41 @@ msgstr "" msgid "Network Total Send" msgstr "" -#: src/views/domain/DomainAdd.vue:137 +#: src/views/domain/DomainAdd.vue:136 msgid "Next" msgstr "" -#: src/routes/index.ts:93 +#: 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:103 #: 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/DirectiveEditorItem.vue:22 +#: 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:156 +#: src/routes/index.ts:158 msgid "Not Found" msgstr "" -#: src/views/domain/cert/CertInfo.vue:19 +#: src/views/domain/cert/CertInfo.vue:14 msgid "Not Valid Before: %{date}" msgstr "" -#: src/views/domain/cert/IssueCert.vue:218 -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 @@ -452,10 +605,11 @@ msgstr "" msgid "Obtaining certificate" msgstr "" -#: src/components/StdDataDisplay/StdCurd.vue:29 -#: src/components/StdDataDisplay/StdTable.vue:43 -#: src/components/StdDataEntry/compontents/StdSelector.vue:12 -#: src/views/domain/DomainList.vue:26 +#: 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/views/domain/DomainList.vue:25 msgid "OK" msgstr "" @@ -476,8 +630,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 +649,11 @@ msgstr "" msgid "Please input your username!" msgstr "" +#: src/routes/index.ts:126 +#: src/views/preference/Preference.vue:2 +msgid "Preference" +msgstr "" + #: src/language/constants.ts:12 msgid "Preparing lego configurations" msgstr "" @@ -528,37 +687,56 @@ 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/preference/Preference.vue:8 +msgid "Run Mode" +msgstr "" + +#: src/views/config/ConfigEdit.vue:70 +#: src/views/domain/DomainEdit.vue:190 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:33 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:34 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:41 +#: src/views/preference/Preference.vue:43 +#: src/views/preference/Preference.vue:44 msgid "Save" msgstr "" -#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32 -#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:33 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:34 #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:35 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:36 msgid "Save Directive" msgstr "" -#: src/views/config/ConfigEdit.vue:36 -#: src/views/domain/DomainAdd.vue:54 +#: src/views/config/ConfigEdit.vue:43 +#: src/views/domain/DomainAdd.vue:55 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37 msgid "Save error %{msg}" msgstr "" -#: src/components/StdDataDisplay/StdCurd.vue:102 +#: src/components/StdDataDisplay/StdBatchEdit.vue:40 +#: src/views/preference/Preference.vue:39 +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/config/ConfigEdit.vue:41 +#: src/views/domain/DomainAdd.vue:44 +#: src/views/domain/DomainEdit.vue:97 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:35 msgid "Saved successfully" msgstr "" -#: src/components/StdDataEntry/compontents/StdSelector.vue:13 +#: src/components/StdDataEntry/components/StdSelector.vue:13 msgid "Selector" msgstr "" @@ -567,15 +745,18 @@ msgstr "" 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:29 +#: 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 "" @@ -583,33 +764,45 @@ 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:209 -#: src/views/domain/DomainAdd.vue:112 +#: src/views/domain/cert/IssueCert.vue:195 +#: src/views/domain/DomainAdd.vue:111 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:117 msgid "Site Logs" msgstr "" -#: src/routes/index.ts:51 +#: src/routes/index.ts:53 msgid "Sites List" msgstr "" -#: src/views/domain/DomainList.vue:19 +#: src/views/cert/Cert.vue:65 +msgid "SSL Certificate Key Path" +msgstr "" + +#: 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 "" @@ -617,7 +810,7 @@ msgstr "" msgid "Storage" msgstr "" -#: src/views/domain/cert/CertInfo.vue:16 +#: src/views/domain/cert/CertInfo.vue:11 msgid "Subject Name: %{name}" msgstr "" @@ -629,12 +822,16 @@ msgstr "" msgid "Table" msgstr "" -#: src/routes/index.ts:85 +#: src/routes/index.ts:95 #: src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "" -#: src/views/domain/cert/IssueCert.vue:222 +#: src/views/preference/Preference.vue:14 +msgid "Terminal Start Command" +msgstr "" + +#: 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 "" @@ -642,16 +839,33 @@ 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 "" -#: src/views/config/Config.vue:17 -#: src/views/domain/DomainList.vue:36 +#: src/views/preference/Preference.vue:20 +msgid "Theme" +msgstr "" + +#: src/views/config/config.ts:14 +msgid "Type" +msgstr "" + +#: 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 "" +#: src/components/StdDataDisplay/StdTable.vue:461 +msgid "Updated successfully" +msgstr "" + #: src/views/dashboard/DashBoard.vue:137 msgid "Uptime:" msgstr "" @@ -669,8 +883,14 @@ msgstr "" msgid "Using HTTP01 challenge provider" msgstr "" -#: src/views/domain/cert/IssueCert.vue:26 -#: src/views/domain/DomainAdd.vue:24 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:10 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:13 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:9 +msgid "View" +msgstr "" + +#: src/views/domain/cert/IssueCert.vue:27 +#: src/views/domain/DomainAdd.vue:22 msgid "Warning" msgstr "" @@ -688,8 +908,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/DirectiveEditorItem.vue:21 +#: 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..956c18db5 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_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 096d9f840..b158d7bc2 100644 Binary files a/frontend/src/language/zh_CN/app.mo and b/frontend/src/language/zh_CN/app.mo differ diff --git a/frontend/src/language/zh_CN/app.po b/frontend/src/language/zh_CN/app.po index 827ed7065..0a1c3c7c7 100644 --- a/frontend/src/language/zh_CN/app.po +++ b/frontend/src/language/zh_CN/app.po @@ -10,23 +10,24 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: easygettext\n" -"X-Generator: Poedit 3.1.1\n" +"X-Generator: Poedit 3.2.2\n" -#: src/routes/index.ts:116 +#: src/routes/index.ts:134 msgid "About" msgstr "关于" -#: src/routes/index.ts:99 src/views/domain/ngx_conf/LogEntry.vue:64 +#: src/routes/index.ts:109 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/user/User.vue:43 +#: 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 "操作" -#: src/components/StdDataDisplay/StdCurd.vue:134 -#: src/components/StdDataDisplay/StdCurd.vue:26 +#: src/components/StdDataDisplay/StdCurd.vue:145 +#: src/components/StdDataDisplay/StdCurd.vue:25 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:26 msgid "Add" msgstr "添加" @@ -36,45 +37,73 @@ 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:57 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 -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/DirectiveEditorItem.vue:20 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 "您确定要删除这个 Location?" +#: src/views/domain/ngx_conf/ConfigTemplate.vue:11 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:12 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:15 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:19 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:20 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:23 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:29 +msgid "Author" +msgstr "作者" + +#: src/views/preference/Preference.vue:22 +#: src/views/preference/Preference.vue:23 +msgid "Auto" +msgstr "自动" + +#: 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 "自动刷新" -#: src/views/domain/cert/IssueCert.vue:78 +#: src/views/domain/cert/IssueCert.vue:71 msgid "Auto-renewal disabled for %{name}" msgstr "成功关闭 %{name} 自动续签" -#: src/views/domain/cert/IssueCert.vue:72 +#: src/views/domain/cert/IssueCert.vue:65 msgid "Auto-renewal enabled for %{name}" msgstr "成功启用 %{name} 自动续签" -#: src/views/domain/DomainEdit.vue:178 src/views/nginx_log/NginxLog.vue:172 +#: src/views/config/Config.vue:16 src/views/config/Config.vue:17 +#: src/views/config/Config.vue:27 src/views/config/Config.vue:5 +#: src/views/config/ConfigEdit.vue:64 src/views/domain/DomainEdit.vue:187 +#: src/views/nginx_log/NginxLog.vue:173 msgid "Back" msgstr "返回" @@ -86,40 +115,61 @@ msgstr "返回首页" 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/StdDataEntry/compontents/StdSelector.vue:11 -#: src/views/config/ConfigEdit.vue:49 +#: src/components/StdDataDisplay/StdBatchEdit.vue:7 +#: src/components/StdDataDisplay/StdCurd.vue:27 +#: src/components/StdDataEntry/components/StdSelector.vue:11 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:35 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/NgxConfigEditor.vue:175 +#: src/routes/index.ts:87 src/views/cert/Cert.vue:2 +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 +#: src/views/domain/ngx_conf/NgxConfigEditor.vue:180 msgid "Comments" msgstr "注释" -#: src/views/domain/DomainAdd.vue:12 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:61 +msgid "Config Templates" +msgstr "配置" + +#: src/views/domain/DomainAdd.vue:11 msgid "Configuration Name" msgstr "配置名称" @@ -131,8 +181,9 @@ 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/directive/DirectiveEditorItem.vue:37 +#: src/views/domain/ngx_conf/LocationEditor.vue:37 +#: src/views/domain/ngx_conf/LocationEditor.vue:53 msgid "Content" msgstr "内容" @@ -142,9 +193,9 @@ msgstr "CPU 状态" #: src/views/dashboard/DashBoard.vue:153 msgid "CPU:" -msgstr "" +msgstr "CPU:" -#: src/views/domain/DomainAdd.vue:150 +#: src/views/domain/DomainAdd.vue:149 msgid "Create Another" msgstr "再创建一个" @@ -156,7 +207,21 @@ msgstr "创建时间" msgid "Creating client facilitates communication with the CA server" msgstr "正在创建客户端用于与 CA 服务器通信" -#: src/routes/index.ts:27 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:22 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:23 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:26 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:32 +#: src/views/domain/ngx_conf/NgxConfigEditor.vue:6 +#: src/views/domain/ngx_conf/NgxConfigEditor.vue:7 +msgid "Custom" +msgstr "自定义" + +#: src/views/preference/Preference.vue:28 +#: src/views/preference/Preference.vue:29 +msgid "Dark" +msgstr "深色" + +#: src/routes/index.ts:29 msgid "Dashboard" msgstr "仪表盘" @@ -164,41 +229,58 @@ 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 "删除" -#: 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 +#: src/views/domain/DomainList.vue:81 msgid "Delete site: %{site_name}" msgstr "删除站点: %{site_name}" +#: src/views/domain/ngx_conf/ConfigTemplate.vue:12 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:13 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:16 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:20 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:21 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:24 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:30 +msgid "Description" +msgstr "描述" + #: src/views/other/About.vue:7 src/views/other/About.vue:8 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 "指令" +#: 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:73 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/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 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 "禁用成功" @@ -206,19 +288,23 @@ msgstr "禁用成功" msgid "Disk IO" msgstr "磁盘 IO" -#: src/views/domain/DomainAdd.vue:60 +#: src/views/cert/Cert.vue:32 +msgid "Domain" +msgstr "域名" + +#: src/views/domain/DomainAdd.vue:58 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:79 src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "编辑配置" -#: src/routes/index.ts:59 +#: src/routes/index.ts:61 msgid "Edit Site" msgstr "编辑站点" @@ -226,11 +312,11 @@ msgstr "编辑站点" msgid "Email (*)" msgstr "邮箱 (*)" -#: src/views/domain/cert/IssueCert.vue:74 +#: src/views/domain/cert/IssueCert.vue:67 msgid "Enable auto-renewal failed for %{name}" msgstr "启用 %{name} 自动续签失败" -#: src/views/domain/DomainAdd.vue:50 +#: src/views/domain/DomainAdd.vue:51 msgid "Enable failed" msgstr "启用失败" @@ -238,39 +324,43 @@ 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/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 +#: 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:47 src/views/domain/DomainEdit.vue:109 +#: src/views/domain/DomainList.vue:59 msgid "Enabled successfully" msgstr "启用成功" -#: src/views/domain/cert/IssueCert.vue:17 +#: src/views/domain/cert/IssueCert.vue:18 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:113 src/views/domain/ngx_conf/LogEntry.vue:68 msgid "Error Logs" msgstr "错误日志" -#: src/views/domain/cert/CertInfo.vue:17 +#: src/views/domain/cert/CertInfo.vue:12 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 "导出" -#: 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}" @@ -278,6 +368,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 "未找到文件" @@ -290,7 +384,19 @@ msgstr "过滤" msgid "Finished" msgstr "完成" -#: src/components/StdDataEntry/compontents/StdPassword.vue:42 +#: src/views/config/ConfigEdit.vue:67 +msgid "Format Code" +msgstr "代码格式化" + +#: src/views/config/ConfigEdit.vue:52 +msgid "Format error %{msg}" +msgstr "保存错误 %{msg}" + +#: src/views/config/ConfigEdit.vue:50 +msgid "Format successfully" +msgstr "保存成功" + +#: src/components/StdDataEntry/components/StdPassword.vue:42 msgid "Generate" msgstr "生成" @@ -298,15 +404,23 @@ msgstr "生成" msgid "Generating private key for registering account" msgstr "正在生成私钥用于注册账户" -#: src/views/domain/cert/IssueCert.vue:103 +#: src/views/domain/cert/IssueCert.vue:96 msgid "Getting the certificate, please wait..." msgstr "正在获取证书,请稍等..." -#: src/routes/index.ts:20 +#: src/routes/index.ts:22 msgid "Home" msgstr "首页" -#: src/routes/index.ts:126 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:144 src/views/other/Install.vue:128 msgid "Install" msgstr "安装" @@ -314,7 +428,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 "中级证书颁发机构: %{issuer}" @@ -322,23 +436,34 @@ 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:25 +#: src/views/preference/Preference.vue:26 +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:150 src/views/other/Login.vue:103 msgid "Login" msgstr "登录" @@ -350,7 +475,7 @@ msgstr "登录成功" msgid "Logout successful" msgstr "登出成功" -#: src/views/domain/cert/IssueCert.vue:226 +#: 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." @@ -358,15 +483,15 @@ msgstr "" "在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 " "HTTPChallengePort (默认: 9180)" -#: src/routes/index.ts:68 +#: src/routes/index.ts:70 msgid "Manage Configs" msgstr "配置管理" -#: src/routes/index.ts:43 src/views/domain/DomainList.vue:2 +#: src/routes/index.ts:45 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:37 src/views/user/User.vue:2 msgid "Manage Users" msgstr "用户管理" @@ -378,20 +503,26 @@ 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 "修改" -#: src/views/domain/DomainAdd.vue:147 +#: src/views/domain/DomainAdd.vue:146 msgid "Modify Config" msgstr "修改配置文件" -#: src/views/config/Config.vue:12 src/views/domain/DomainList.vue:14 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:10 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:9 +msgid "Multi-line Directive" +msgstr "单行指令" + +#: 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 "名称" @@ -411,49 +542,56 @@ msgstr "下载流量" msgid "Network Total Send" msgstr "上传流量" -#: src/views/domain/DomainAdd.vue:137 +#: src/views/domain/DomainAdd.vue:136 msgid "Next" msgstr "下一步" -#: src/routes/index.ts:93 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:103 src/views/nginx_log/NginxLog.vue:2 msgid "Nginx Log" 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/DirectiveEditorItem.vue:22 +#: 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:156 src/routes/index.ts:158 msgid "Not Found" msgstr "找不到页面" -#: src/views/domain/cert/CertInfo.vue:19 +#: src/views/domain/cert/CertInfo.vue:14 msgid "Not Valid Before: %{date}" msgstr "此前无效: %{date}" -#: src/views/domain/cert/IssueCert.vue:218 -msgid "" -"Note: The server_name in the current configuration must be the domain name " -"you need to get the certificate." -msgstr "注意:当前配置中的 server_name 必须为需要申请证书的域名。" +#: src/views/domain/cert/IssueCert.vue:38 +msgid "Note" +msgstr "注意" #: src/language/constants.ts:16 src/views/domain/cert/IssueCert.vue:3 msgid "Obtaining certificate" msgstr "正在获取证书" -#: src/components/StdDataDisplay/StdCurd.vue:29 -#: src/components/StdDataDisplay/StdTable.vue:43 -#: src/components/StdDataEntry/compontents/StdSelector.vue:12 -#: src/views/domain/DomainList.vue:26 +#: 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/views/domain/DomainList.vue:25 msgid "OK" msgstr "确定" #: src/views/dashboard/DashBoard.vue:147 msgid "OS:" -msgstr "" +msgstr "OS:" #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:22 msgid "Params" @@ -467,8 +605,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 "路径" @@ -484,6 +622,10 @@ msgstr "请输入您的密码!" msgid "Please input your username!" msgstr "请输入您的用户名!" +#: src/routes/index.ts:126 src/views/preference/Preference.vue:2 +msgid "Preference" +msgstr "偏好设置" + #: src/language/constants.ts:12 msgid "Preparing lego configurations" msgstr "正在准备 Lego 的配置" @@ -516,34 +658,53 @@ msgstr "正在注册用户" msgid "Reloading nginx" msgstr "正在重载 Nginx" +#: 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/preference/Preference.vue:8 +msgid "Run Mode" +msgstr "运行模式" + +#: src/views/config/ConfigEdit.vue:70 src/views/domain/DomainEdit.vue:190 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:33 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:34 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:41 +#: src/views/preference/Preference.vue:43 +#: src/views/preference/Preference.vue:44 msgid "Save" msgstr "保存" -#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32 -#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:33 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:34 #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:35 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:36 msgid "Save Directive" msgstr "保存指令" -#: src/views/config/ConfigEdit.vue:36 src/views/domain/DomainAdd.vue:54 +#: src/views/config/ConfigEdit.vue:43 src/views/domain/DomainAdd.vue:55 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37 msgid "Save error %{msg}" msgstr "保存错误 %{msg}" -#: src/components/StdDataDisplay/StdCurd.vue:102 +#: src/components/StdDataDisplay/StdBatchEdit.vue:40 +#: src/views/preference/Preference.vue:39 +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/config/ConfigEdit.vue:41 src/views/domain/DomainAdd.vue:44 +#: src/views/domain/DomainEdit.vue:97 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:35 msgid "Saved successfully" msgstr "保存成功" -#: src/components/StdDataEntry/compontents/StdSelector.vue:13 +#: src/components/StdDataEntry/components/StdSelector.vue:13 msgid "Selector" msgstr "选择器" @@ -551,12 +712,14 @@ msgstr "选择器" 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/views/other/Install.vue:71 +#: 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:29 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 "服务器错误" @@ -564,32 +727,44 @@ 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 "未在指令集合中找到 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:111 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 +#: src/routes/index.ts:117 msgid "Site Logs" msgstr "站点列表" -#: src/routes/index.ts:51 +#: src/routes/index.ts:53 msgid "Sites List" msgstr "站点列表" -#: src/views/domain/DomainList.vue:19 +#: src/views/cert/Cert.vue:65 +msgid "SSL Certificate Key Path" +msgstr "SSL证书密钥路径" + +#: src/views/cert/Cert.vue:58 +msgid "SSL Certificate Path" +msgstr "SSL证书路径" + +#: src/views/cert/Cert.vue:19 +msgid "SSL Certification Content" +msgstr "SSL证书内容" + +#: src/views/cert/Cert.vue:22 +msgid "SSL Certification Key Content" +msgstr "SSL证书密钥内容" + +#: src/views/domain/DomainList.vue:24 msgid "Status" msgstr "状态" @@ -597,23 +772,27 @@ msgstr "状态" msgid "Storage" msgstr "存储" -#: src/views/domain/cert/CertInfo.vue:16 +#: src/views/domain/cert/CertInfo.vue:11 msgid "Subject Name: %{name}" msgstr "主体名称: %{name}" #: src/views/dashboard/DashBoard.vue:36 msgid "Swap" -msgstr "" +msgstr "Swap" #: src/components/StdDataDisplay/StdCurd.vue:3 msgid "Table" msgstr "列表" -#: src/routes/index.ts:85 src/views/pty/Terminal.vue:2 +#: src/routes/index.ts:95 src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "终端" -#: src/views/domain/cert/IssueCert.vue:222 +#: src/views/preference/Preference.vue:14 +msgid "Terminal Start Command" +msgstr "终端启动命令" + +#: 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." @@ -624,15 +803,33 @@ msgstr "" msgid "The filename cannot contain the following characters: %{c}" msgstr "文件名不能包含以下字符: %{c}" +#: 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 "当前配置中的 server_name 必须为需要申请证书的域名。" + #: src/language/constants.ts:6 msgid "The username or password is incorrect" msgstr "用户名或密码错误" -#: src/views/config/Config.vue:17 src/views/domain/DomainList.vue:36 -#: src/views/user/User.vue:37 +#: src/views/preference/Preference.vue:20 +msgid "Theme" +msgstr "主题" + +#: src/views/config/config.ts:14 +msgid "Type" +msgstr "类型" + +#: 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 "修改时间" +#: src/components/StdDataDisplay/StdTable.vue:461 +msgid "Updated successfully" +msgstr "更新成功" + #: src/views/dashboard/DashBoard.vue:137 msgid "Uptime:" msgstr "运行时间:" @@ -649,7 +846,13 @@ msgstr "用户名 (*)" msgid "Using HTTP01 challenge provider" msgstr "使用 HTTP01 challenge provider" -#: src/views/domain/cert/IssueCert.vue:26 src/views/domain/DomainAdd.vue:24 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:10 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:13 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:9 +msgid "View" +msgstr "查看" + +#: src/views/domain/cert/IssueCert.vue:27 src/views/domain/DomainAdd.vue:22 msgid "Warning" msgstr "警告" @@ -666,8 +869,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/DirectiveEditorItem.vue:21 +#: src/views/domain/ngx_conf/LocationEditor.vue:20 msgid "Yes" msgstr "是的" @@ -676,6 +879,12 @@ msgctxt "Project" msgid "License" msgstr "开源许可" +#~ msgid "Are you sure you want to delete ?" +#~ msgstr "您确定要删除吗?" + +#~ msgid "server_name parameters more than one" +#~ msgstr "server_name 指令包含多个参数" + #~ msgid "All logs" #~ msgstr "所有日志" @@ -721,9 +930,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.mo b/frontend/src/language/zh_TW/app.mo new file mode 100644 index 000000000..3c29365c3 Binary files /dev/null and b/frontend/src/language/zh_TW/app.mo differ diff --git a/frontend/src/language/zh_TW/app.po b/frontend/src/language/zh_TW/app.po index 247037de6..1b3d1119d 100644 --- a/frontend/src/language/zh_TW/app.po +++ b/frontend/src/language/zh_TW/app.po @@ -11,25 +11,26 @@ 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:134 msgid "About" msgstr "關於" -#: src/routes/index.ts:99 src/views/domain/ngx_conf/LogEntry.vue:64 +#: src/routes/index.ts:109 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/user/User.vue:43 +#: 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 "操作" -#: src/components/StdDataDisplay/StdCurd.vue:134 -#: src/components/StdDataDisplay/StdCurd.vue:26 +#: src/components/StdDataDisplay/StdCurd.vue:145 +#: src/components/StdDataDisplay/StdCurd.vue:25 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:26 msgid "Add" -msgstr "" +msgstr "新增" #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:31 #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32 @@ -37,93 +38,143 @@ 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:57 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/DirectiveEditorItem.vue:20 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/domain/ngx_conf/ConfigTemplate.vue:11 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:12 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:15 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:19 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:20 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:23 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:29 +msgid "Author" +msgstr "" + +#: src/views/preference/Preference.vue:22 +#: src/views/preference/Preference.vue:23 +msgid "Auto" +msgstr "自動" + +#: src/views/cert/Cert.vue:41 +#, fuzzy +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 "" +msgstr "自動刷新" -#: src/views/domain/cert/IssueCert.vue:78 +#: src/views/domain/cert/IssueCert.vue:71 msgid "Auto-renewal disabled for %{name}" msgstr "已關閉 %{name} 自動續簽" -#: src/views/domain/cert/IssueCert.vue:72 +#: src/views/domain/cert/IssueCert.vue:65 msgid "Auto-renewal enabled for %{name}" msgstr "已啟用 %{name} 自動續簽" -#: src/views/domain/DomainEdit.vue:178 src/views/nginx_log/NginxLog.vue:172 +#: src/views/config/Config.vue:16 src/views/config/Config.vue:17 +#: src/views/config/Config.vue:27 src/views/config/Config.vue:5 +#: src/views/config/ConfigEdit.vue:64 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/StdDataEntry/compontents/StdSelector.vue:11 -#: src/views/config/ConfigEdit.vue:49 +#: src/components/StdDataDisplay/StdBatchEdit.vue:7 +#: src/components/StdDataDisplay/StdCurd.vue:27 +#: src/components/StdDataEntry/components/StdSelector.vue:11 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:35 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/NgxConfigEditor.vue:175 +#: src/routes/index.ts:87 src/views/cert/Cert.vue:2 +#, fuzzy +msgid "Certification" +msgstr "此憑證有效" + +#: 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 "正在獲取證書,請稍等..." + +#: 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 +#: src/views/domain/ngx_conf/NgxConfigEditor.vue:180 msgid "Comments" msgstr "註釋" -#: src/views/domain/DomainAdd.vue:12 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:61 +#, fuzzy +msgid "Config Templates" +msgstr "配置" + +#: src/views/domain/DomainAdd.vue:11 msgid "Configuration Name" msgstr "配置名稱" @@ -135,8 +186,9 @@ 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/directive/DirectiveEditorItem.vue:37 +#: src/views/domain/ngx_conf/LocationEditor.vue:37 +#: src/views/domain/ngx_conf/LocationEditor.vue:53 msgid "Content" msgstr "內容" @@ -148,7 +200,7 @@ msgstr "中央處理器狀態" msgid "CPU:" msgstr "中央處理器:" -#: src/views/domain/DomainAdd.vue:150 +#: src/views/domain/DomainAdd.vue:149 msgid "Create Another" msgstr "再創建一個" @@ -158,9 +210,23 @@ msgstr "建立時間" #: src/language/constants.ts:13 msgid "Creating client facilitates communication with the CA server" +msgstr "創建客戶端方便與CA服務器通信" + +#: src/views/domain/ngx_conf/ConfigTemplate.vue:22 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:23 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:26 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:32 +#: src/views/domain/ngx_conf/NgxConfigEditor.vue:6 +#: src/views/domain/ngx_conf/NgxConfigEditor.vue:7 +msgid "Custom" msgstr "" -#: src/routes/index.ts:27 +#: src/views/preference/Preference.vue:28 +#: src/views/preference/Preference.vue:29 +msgid "Dark" +msgstr "深色" + +#: src/routes/index.ts:29 msgid "Dashboard" msgstr "儀表盤" @@ -168,42 +234,58 @@ 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/domain/ngx_conf/ConfigTemplate.vue:12 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:13 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:16 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:20 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:21 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:24 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:30 +msgid "Description" +msgstr "" #: src/views/other/About.vue:7 src/views/other/About.vue:8 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 "指令" +#: 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:73 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/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 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 "禁用成功" @@ -211,19 +293,23 @@ msgstr "禁用成功" msgid "Disk IO" msgstr "磁碟 IO" -#: src/views/domain/DomainAdd.vue:60 +#: src/views/cert/Cert.vue:32 +msgid "Domain" +msgstr "" + +#: src/views/domain/DomainAdd.vue:58 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:79 src/views/config/ConfigEdit.vue:2 msgid "Edit Configuration" msgstr "編輯配置" -#: src/routes/index.ts:59 +#: src/routes/index.ts:61 msgid "Edit Site" msgstr "編輯站點" @@ -231,11 +317,11 @@ msgstr "編輯站點" msgid "Email (*)" msgstr "郵箱 (*)" -#: src/views/domain/cert/IssueCert.vue:74 +#: src/views/domain/cert/IssueCert.vue:67 msgid "Enable auto-renewal failed for %{name}" msgstr "啟用 %{name} 自動續簽失敗" -#: src/views/domain/DomainAdd.vue:50 +#: src/views/domain/DomainAdd.vue:51 msgid "Enable failed" msgstr "啟用失敗" @@ -243,44 +329,52 @@ 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/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 +#: 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:47 src/views/domain/DomainEdit.vue:109 +#: src/views/domain/DomainList.vue:59 msgid "Enabled successfully" msgstr "啟用成功" -#: src/views/domain/cert/IssueCert.vue:17 +#: src/views/domain/cert/IssueCert.vue:18 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:113 src/views/domain/ngx_conf/LogEntry.vue:68 msgid "Error Logs" -msgstr "" +msgstr "錯誤日志" -#: src/views/domain/cert/CertInfo.vue:17 +#: src/views/domain/cert/CertInfo.vue:12 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 "獲取證書信息失敗" + +#: src/views/config/config.ts:22 +msgid "File" msgstr "" #: src/views/other/Error.vue:3 src/views/other/Error.vue:4 @@ -289,63 +383,96 @@ 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/compontents/StdPassword.vue:42 -msgid "Generate" +#: src/views/config/ConfigEdit.vue:67 +msgid "Format Code" msgstr "" +#: src/views/config/ConfigEdit.vue:52 +#, fuzzy +msgid "Format error %{msg}" +msgstr "儲存錯誤 %{msg}" + +#: src/views/config/ConfigEdit.vue:50 +#, fuzzy +msgid "Format successfully" +msgstr "保存成功" + +#: src/components/StdDataEntry/components/StdPassword.vue:42 +msgid "Generate" +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:96 msgid "Getting the certificate, please wait..." msgstr "正在獲取憑證,請稍等..." -#: src/routes/index.ts:20 +#: src/routes/index.ts:22 msgid "Home" msgstr "首頁" -#: src/routes/index.ts:126 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:144 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 +#: src/views/domain/cert/CertInfo.vue:10 msgid "Intermediate Certification Authorities: %{issuer}" msgstr "中級憑證頒發機構: %{issuer}" #: src/language/constants.ts:21 -#, fuzzy msgid "Issued certificate successfully" -msgstr "啟用成功" +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:25 +#: src/views/preference/Preference.vue:26 +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:150 src/views/other/Login.vue:103 msgid "Login" msgstr "登入" @@ -357,24 +484,23 @@ msgstr "登入成功" msgid "Logout successful" msgstr "登出成功" -#: src/views/domain/cert/IssueCert.vue:226 -#, fuzzy +#: 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 "" -"在獲取憑證前,請確保配置檔案中已將 .well-known 目錄反向代理到 " +"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 " "HTTPChallengePort (預設: 9180)" -#: src/routes/index.ts:68 +#: src/routes/index.ts:70 msgid "Manage Configs" msgstr "配置管理" -#: src/routes/index.ts:43 src/views/domain/DomainList.vue:2 +#: src/routes/index.ts:45 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:37 src/views/user/User.vue:2 msgid "Manage Users" msgstr "使用者管理" @@ -386,21 +512,27 @@ 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 +#: src/views/domain/DomainAdd.vue:146 msgid "Modify Config" msgstr "修改配置" -#: src/views/config/Config.vue:12 src/views/domain/DomainList.vue:14 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:10 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:9 +#, fuzzy +msgid "Multi-line Directive" +msgstr "單行指令" + +#: 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 "名稱" @@ -420,44 +552,52 @@ msgstr "下載流量" msgid "Network Total Send" msgstr "上傳流量" -#: src/views/domain/DomainAdd.vue:137 +#: src/views/domain/DomainAdd.vue:136 msgid "Next" msgstr "下一步" -#: src/routes/index.ts:93 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:103 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/DirectiveEditorItem.vue:22 +#: 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:156 src/routes/index.ts:158 msgid "Not Found" msgstr "找不到頁面" -#: src/views/domain/cert/CertInfo.vue:19 +#: src/views/domain/cert/CertInfo.vue:14 msgid "Not Valid Before: %{date}" msgstr "此前無效: %{date}" -#: src/views/domain/cert/IssueCert.vue:218 -#, fuzzy -msgid "" -"Note: The server_name in the current configuration must be the domain name " -"you need to get the certificate." -msgstr "注意:當前配置中的 server_name 必須為需要申請憑證的域名。" +#: src/views/domain/cert/IssueCert.vue:38 +msgid "Note" +msgstr "" #: 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/StdDataEntry/compontents/StdSelector.vue:12 -#: src/views/domain/DomainList.vue:26 +#: 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/views/domain/DomainList.vue:25 msgid "OK" msgstr "確定" @@ -477,8 +617,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 +634,21 @@ msgstr "請輸入您的密碼!" msgid "Please input your username!" msgstr "請輸入您的使用者名稱!" +#: src/routes/index.ts:126 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,54 +664,75 @@ 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/preference/Preference.vue:8 +#, fuzzy +msgid "Run Mode" +msgstr "高階模式" -#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:181 +#: src/views/config/ConfigEdit.vue:70 src/views/domain/DomainEdit.vue:190 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:33 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:34 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:41 +#: src/views/preference/Preference.vue:43 +#: src/views/preference/Preference.vue:44 msgid "Save" msgstr "儲存" -#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32 -#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:33 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:34 #: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:35 +#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:36 msgid "Save Directive" msgstr "儲存指令" -#: src/views/config/ConfigEdit.vue:36 src/views/domain/DomainAdd.vue:54 +#: src/views/config/ConfigEdit.vue:43 src/views/domain/DomainAdd.vue:55 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37 msgid "Save error %{msg}" msgstr "儲存錯誤 %{msg}" -#: src/components/StdDataDisplay/StdCurd.vue:102 -#, fuzzy +#: src/components/StdDataDisplay/StdBatchEdit.vue:40 +#: src/views/preference/Preference.vue:39 +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/config/ConfigEdit.vue:41 src/views/domain/DomainAdd.vue:44 +#: src/views/domain/DomainEdit.vue:97 +#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:35 msgid "Saved successfully" msgstr "儲存成功" -#: src/components/StdDataEntry/compontents/StdSelector.vue:13 +#: src/components/StdDataEntry/components/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/views/other/Install.vue:71 +#: 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:29 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 "伺服器錯誤" @@ -576,33 +740,48 @@ 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 "未在指令集合中找到 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:111 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:117 msgid "Site Logs" -msgstr "站點列表" +msgstr "網站日誌" -#: src/routes/index.ts:51 +#: src/routes/index.ts:53 msgid "Sites List" msgstr "站點列表" -#: src/views/domain/DomainList.vue:19 +#: src/views/cert/Cert.vue:65 +#, fuzzy +msgid "SSL Certificate Key Path" +msgstr "憑證狀態" + +#: src/views/cert/Cert.vue:58 +#, fuzzy +msgid "SSL Certificate Path" +msgstr "憑證狀態" + +#: src/views/cert/Cert.vue:19 +#, fuzzy +msgid "SSL Certification Content" +msgstr "憑證狀態" + +#: src/views/cert/Cert.vue:22 +#, fuzzy +msgid "SSL Certification Key Content" +msgstr "憑證狀態" + +#: src/views/domain/DomainList.vue:24 msgid "Status" msgstr "狀態" @@ -610,7 +789,7 @@ msgstr "狀態" msgid "Storage" msgstr "儲存" -#: src/views/domain/cert/CertInfo.vue:16 +#: src/views/domain/cert/CertInfo.vue:11 msgid "Subject Name: %{name}" msgstr "主體名稱: %{name}" @@ -619,36 +798,57 @@ 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:95 src/views/pty/Terminal.vue:2 msgid "Terminal" msgstr "終端" -#: src/views/domain/cert/IssueCert.vue:222 -#, fuzzy +#: src/views/preference/Preference.vue:14 +msgid "Terminal Start Command" +msgstr "" + +#: 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 "" -"系統將會每小時檢測一次該域名憑證,若距離上次簽發已超過1個月,則將自動續簽。" -"
如果您之前沒有憑證,請先點選「從 Let's Encrypt 獲取憑證」。" +"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。" +"
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。" #: src/views/other/Install.vue:54 msgid "The filename cannot contain the following characters: %{c}" msgstr "檔名不能包含以下字元: %{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 "注意:當前配置中的 server_name 必須為需要申請證書的域名。" + #: src/language/constants.ts:6 msgid "The username or password is incorrect" +msgstr "用戶名或密碼不正確" + +#: src/views/preference/Preference.vue:20 +msgid "Theme" +msgstr "外觀樣式" + +#: src/views/config/config.ts:14 +msgid "Type" msgstr "" -#: src/views/config/Config.vue:17 src/views/domain/DomainList.vue:36 -#: src/views/user/User.vue:37 +#: 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 "修改時間" +#: src/components/StdDataDisplay/StdTable.vue:461 +msgid "Updated successfully" +msgstr "已成功更新" + #: src/views/dashboard/DashBoard.vue:137 msgid "Uptime:" msgstr "執行時間:" @@ -663,9 +863,15 @@ msgstr "使用者名稱 (*)" #: src/language/constants.ts:14 msgid "Using HTTP01 challenge provider" +msgstr "使用 HTTP01 挑戰提供者" + +#: src/views/domain/ngx_conf/ConfigTemplate.vue:10 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:13 +#: src/views/domain/ngx_conf/ConfigTemplate.vue:9 +msgid "View" msgstr "" -#: src/views/domain/cert/IssueCert.vue:26 src/views/domain/DomainAdd.vue:24 +#: src/views/domain/cert/IssueCert.vue:27 src/views/domain/DomainAdd.vue:22 msgid "Warning" msgstr "警告" @@ -676,14 +882,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/DirectiveEditorItem.vue:21 +#: src/views/domain/ngx_conf/LocationEditor.vue:20 msgid "Yes" msgstr "是的" @@ -692,6 +898,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 未找到頁面" @@ -728,9 +941,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/layouts/BaseLayout.vue b/frontend/src/layouts/BaseLayout.vue index 729f1b51a..c26a39270 100644 --- a/frontend/src/layouts/BaseLayout.vue +++ b/frontend/src/layouts/BaseLayout.vue @@ -39,7 +39,7 @@ const lang = computed(() => { diff --git a/frontend/src/views/domain/ngx_conf/directive/DirectiveEditor.vue b/frontend/src/views/domain/ngx_conf/directive/DirectiveEditor.vue index 0ed77bc89..9b7a4e482 100644 --- a/frontend/src/views/domain/ngx_conf/directive/DirectiveEditor.vue +++ b/frontend/src/views/domain/ngx_conf/directive/DirectiveEditor.vue @@ -1,17 +1,13 @@ + + + + diff --git a/frontend/src/views/nginx_log/NginxLog.vue b/frontend/src/views/nginx_log/NginxLog.vue index b7cca9917..bd2306c3d 100644 --- a/frontend/src/views/nginx_log/NginxLog.vue +++ b/frontend/src/views/nginx_log/NginxLog.vue @@ -68,8 +68,8 @@ function init() { nginx_log.page(0, { conf_name: (route.query.conf_name as string), type: logType(), - server_idx: 0, - directive_idx: 0 + server_idx: parseInt(route.query.server_idx as string), + directive_idx: parseInt(route.query.directive_idx as string) }).then(r => { page.value = r.page - 1 addLog(r.content) diff --git a/frontend/src/views/preference/Preference.vue b/frontend/src/views/preference/Preference.vue new file mode 100644 index 000000000..8cd7e4f4f --- /dev/null +++ b/frontend/src/views/preference/Preference.vue @@ -0,0 +1,101 @@ + + + + + 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 006b322ef..ae00f274e 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":0,"total_build":0} \ No newline at end of file diff --git a/frontend/yarn.lock b/frontend/yarn.lock index e627621e4..4be7d1368 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -361,20 +361,120 @@ resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz#75b4c27948c81e88ccd3a8902047bcd797f38d32" integrity sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw== -"@esbuild/android-arm@0.15.13": - version "0.15.13" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.13.tgz#ce11237a13ee76d5eae3908e47ba4ddd380af86a" - integrity sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw== +"@esbuild/android-arm64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.16.13.tgz#1fc9bfbff0bac558008b2ad7242db1c8024d8cfd" + integrity sha512-r4xetsd1ez1NF9/9R2f9Q6AlxqiZLwUqo7ICOcvEVwopVkXUcspIjEbJk0EVTgT6Cp5+ymzGPT6YNV0ievx4yA== + +"@esbuild/android-arm@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.16.13.tgz#df3317286eed68c727daf39c2d585625f9c2f170" + integrity sha512-JmtqThupn9Yf+FzANE+GG73ASUkssnPwOsndUElhp23685QzRK+MO1UompOlBaXV9D5FTuYcPnw7p4mCq2YbZQ== + +"@esbuild/android-x64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.16.13.tgz#c34826c4bdc57c60cbfb8d5bbd2306a89225626a" + integrity sha512-hKt1bFht/Vtp0xJ0ZVzFMnPy1y1ycmM3KNnp3zsyZfQmw7nhs2WLO4vxdR5YG+6RsHKCb2zbZ3VwlC0Tij0qyA== + +"@esbuild/darwin-arm64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.13.tgz#0b80c8580c262ccfb1203053201cf19c6f7b4cdb" + integrity sha512-ogrVuNi2URocrr3Ps20f075EMm9V7IeenOi9FRj4qdbT6mQlwLuP4l90PW2iBrKERx0oRkcZprEUNsz/3xd7ww== + +"@esbuild/darwin-x64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.16.13.tgz#f1a6c9ea67d4eaaf4944e1cbceb800eabc6e7e74" + integrity sha512-Agajik9SBGiKD7FPXE+ExW6x3MgA/dUdpZnXa9y1tyfE4lKQx+eQiknSdrBnWPeqa9wL0AOvkhghmYhpVkyqkA== + +"@esbuild/freebsd-arm64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.13.tgz#d1a45ac5c4a1be566c4eefbadbe5a967288ad338" + integrity sha512-KxMO3/XihBcHM+xQUM6nQZO1SgQuOsd1DCnKF1a4SIf/i5VD45vrqN3k8ePgFrEbMi7m5JeGmvNqwJXinF0a4Q== + +"@esbuild/freebsd-x64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.13.tgz#ec64a31cabb08343bb4520a221324b40509dffc8" + integrity sha512-Ez15oqV1vwvZ30cVLeBW14BsWq/fdWNQGMOxxqaSJVQVLqHhvgfQ7gxGDiN9tpJdeQhqJO+Q0r02/Tce5+USNg== + +"@esbuild/linux-arm64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.16.13.tgz#e8db3c3751b32ecf801751424eae43f6863a2ee7" + integrity sha512-qi5n7KwcGViyJeZeQnu8fB6dC3Mlm5PGaqSv2HhQDDx/MPvVfQGNMcv7zcBL4qk3FkuWhGVwXkjQ76x7R0PWlA== + +"@esbuild/linux-arm@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.16.13.tgz#ac0c8e9f3db8d418f588ae250e9c66ffdcf3cd82" + integrity sha512-18dLd2L3mda+iFj6sswyBMSh2UwniamD9M4DwPv8VM+9apRFlQ5IGKxBdumnTuOI4NvwwAernmUseWhYQ9k+rg== + +"@esbuild/linux-ia32@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.16.13.tgz#41ee9bd3b7161ab681fab6cb3990a3f5c08a9940" + integrity sha512-2489Xad9sr+6GD7nB913fUqpCsSwVwgskkQTq4Or2mZntSPYPebyJm8l1YruHo7oqYMTGV6RiwGE4gRo3H+EPQ== "@esbuild/linux-loong64@0.14.53": version "0.14.53" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.53.tgz#251b4cd6760fadb4d68a05815e6dc5e432d69cd6" integrity sha512-W2dAL6Bnyn4xa/QRSU3ilIK4EzD5wgYXKXJiS1HDF5vU3675qc2bvFyLwbUcdmssDveyndy7FbitrCoiV/eMLg== -"@esbuild/linux-loong64@0.15.13": - version "0.15.13" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz#64e8825bf0ce769dac94ee39d92ebe6272020dfc" - integrity sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag== +"@esbuild/linux-loong64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.16.13.tgz#e4a832708e0b47078b91413edcfdb6af88c854a3" + integrity sha512-x8KplRu9Y43Px8I9YS+sPBwQ+fw44Mvp2BPVADopKDWz+h3fcj1BvRU58kxb89WObmwKX9sWdtYzepL4Fmx03A== + +"@esbuild/linux-mips64el@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.13.tgz#30d8571b71e0b8bf25fc5ef11422221ed23cdacc" + integrity sha512-qhhdWph9FLwD9rVVC/nUf7k2U4NZIA6/mGx0B7+O6PFV0GjmPA2E3zDQ4NUjq9P26E0DeAZy9akH9dYcUBRU7A== + +"@esbuild/linux-ppc64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.13.tgz#32a3855d4b79ba1d2b63dab592cb9f0d4a9ba485" + integrity sha512-cVWAPKsrRVxI1jCeJHnYSbE3BrEU+pZTZK2gfao9HRxuc+3m4+RLfs3EVEpGLmMKEcWfVCB9wZ3yNxnknutGKQ== + +"@esbuild/linux-riscv64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.13.tgz#6139202858da8202724d7079102614c269524f34" + integrity sha512-Agb7dbRyZWnmPn5Vvf0eyqaEUqSsaIUwwyInu2EoFTaIDRp093QU2M5alUyOooMLkRbD1WvqQNwx08Z/g+SAcQ== + +"@esbuild/linux-s390x@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.16.13.tgz#df3550a51e4155cde31486e01d8121f078e959ae" + integrity sha512-AqRBIrc/+kl08ahliNG+EyU+j41wIzQfwBTKpi80cCDiYvYFPuXjvzZsD9muiu58Isj0RVni9VgC4xK/AnSW4g== + +"@esbuild/linux-x64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.16.13.tgz#deb7951829ea5930e0d88440aeb5df0756ebb2d0" + integrity sha512-S4wn2BimuhPcoArRtVrdHUKIymCCZcYAXQE47kUiX4yrUrEX2/ifn5eKNbZ5c1jJKUlh1gC2ESIN+iw3wQax3g== + +"@esbuild/netbsd-x64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.13.tgz#8cba08074263862138cc5c63ad7f9640fe3faa69" + integrity sha512-2c8JWgfUMlQHTdaR5X3xNMwqOyad8kgeCupuVkdm3QkUOzGREjlTETQsK6oHifocYzDCo9FeKcUwsK356SdR+g== + +"@esbuild/openbsd-x64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.13.tgz#4ae19ac63c665424d248ba5c577618dd7bbcebd5" + integrity sha512-Bwh+PmKD/LK+xBjqIpnYnKYj0fIyQJ0YpRxsn0F+WfzvQ2OA+GKDlf8AHosiCns26Q4Dje388jQVwfOBZ1GaFw== + +"@esbuild/sunos-x64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.16.13.tgz#592caacab6b2c7669cd869b51f66dc354da03fc2" + integrity sha512-8wwk6f9XGnhrF94/DBdFM4Xm1JeCyGTCj67r516VS9yvBVQf3Rar54L+XPVDs/oZOokwH+XsktrgkuTMAmjntg== + +"@esbuild/win32-arm64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.16.13.tgz#965ebbe889e4221962250c55facaa1e48130c162" + integrity sha512-Jmwbp/5ArLCiRAHC33ODfcrlIcbP/exXkOEUVkADNJC4e/so2jm+i8IQFvVX/lA2GWvK3GdgcN0VFfp9YITAbg== + +"@esbuild/win32-ia32@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.16.13.tgz#1b04965bcf340ba4879b452ac32df63216d4c87e" + integrity sha512-AX6WjntGjhJHzrPSVvjMD7grxt41koHfAOx6lxLorrpDwwIKKPaGDASPZgvFIZHTbwhOtILW6vAXxYPDsKpDJA== + +"@esbuild/win32-x64@0.16.13": + version "0.16.13" + resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.16.13.tgz#0b0989cf0e7887cb0f3124e705cee68a694b96dd" + integrity sha512-A+U4gM6OOkPS03UgVU08GTpAAAxPsP/8Z4FmneGo4TaVSD99bK9gVJXlqUEPMO/htFXEAht2O6pX4ErtLY5tVg== "@jridgewell/gen-mapping@^0.1.0": version "0.1.1" @@ -1442,201 +1542,101 @@ esbuild-android-64@0.14.53: resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.53.tgz#259bc3ef1399a3cad8f4f67c40ee20779c4de675" integrity sha512-fIL93sOTnEU+NrTAVMIKiAw0YH22HWCAgg4N4Z6zov2t0kY9RAJ50zY9ZMCQ+RT6bnOfDt8gCTnt/RaSNA2yRA== -esbuild-android-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz#5f25864055dbd62e250f360b38b4c382224063af" - integrity sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g== - esbuild-android-arm64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.53.tgz#2158253d4e8f9fdd2a081bbb4f73b8806178841e" integrity sha512-PC7KaF1v0h/nWpvlU1UMN7dzB54cBH8qSsm7S9mkwFA1BXpaEOufCg8hdoEI1jep0KeO/rjZVWrsH8+q28T77A== -esbuild-android-arm64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz#d8820f999314efbe8e0f050653a99ff2da632b0f" - integrity sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w== - esbuild-darwin-64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.53.tgz#b4681831fd8f8d06feb5048acbe90d742074cc2a" integrity sha512-gE7P5wlnkX4d4PKvLBUgmhZXvL7lzGRLri17/+CmmCzfncIgq8lOBvxGMiQ4xazplhxq+72TEohyFMZLFxuWvg== -esbuild-darwin-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz#99ae7fdaa43947b06cd9d1a1c3c2c9f245d81fd0" - integrity sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg== - esbuild-darwin-arm64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.53.tgz#d267d957852d121b261b3f76ead86e5b5463acc9" integrity sha512-otJwDU3hnI15Q98PX4MJbknSZ/WSR1I45il7gcxcECXzfN4Mrpft5hBDHXNRnCh+5858uPXBXA1Vaz2jVWLaIA== -esbuild-darwin-arm64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz#bafa1814354ad1a47adcad73de416130ef7f55e3" - integrity sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A== - esbuild-freebsd-64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.53.tgz#aca2af6d72b537fe66a38eb8f374fb66d4c98ca0" integrity sha512-WkdJa8iyrGHyKiPF4lk0MiOF87Q2SkE+i+8D4Cazq3/iqmGPJ6u49je300MFi5I2eUsQCkaOWhpCVQMTKGww2w== -esbuild-freebsd-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz#84ef85535c5cc38b627d1c5115623b088d1de161" - integrity sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA== - esbuild-freebsd-arm64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.53.tgz#76282e19312d914c34343c8a7da6cc5f051580b9" integrity sha512-9T7WwCuV30NAx0SyQpw8edbKvbKELnnm1FHg7gbSYaatH+c8WJW10g/OdM7JYnv7qkimw2ZTtSA+NokOLd2ydQ== -esbuild-freebsd-arm64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz#033f21de434ec8e0c478054b119af8056763c2d8" - integrity sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q== - esbuild-linux-32@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.53.tgz#1045d34cf7c5faaf2af3b29cc1573b06580c37e5" integrity sha512-VGanLBg5en2LfGDgLEUxQko2lqsOS7MTEWUi8x91YmsHNyzJVT/WApbFFx3MQGhkf+XdimVhpyo5/G0PBY91zg== -esbuild-linux-32@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz#54290ea8035cba0faf1791ce9ae6693005512535" - integrity sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w== - esbuild-linux-64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.53.tgz#ab3f2ee2ebb5a6930c72d9539cb34b428808cbe4" integrity sha512-pP/FA55j/fzAV7N9DF31meAyjOH6Bjuo3aSKPh26+RW85ZEtbJv9nhoxmGTd9FOqjx59Tc1ZbrJabuiXlMwuZQ== -esbuild-linux-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz#4264249281ea388ead948614b57fb1ddf7779a2c" - integrity sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A== - esbuild-linux-arm64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.53.tgz#1f5530412f6690949e78297122350488d3266cfe" integrity sha512-GDmWITT+PMsjCA6/lByYk7NyFssW4Q6in32iPkpjZ/ytSyH+xeEx8q7HG3AhWH6heemEYEWpTll/eui3jwlSnw== -esbuild-linux-arm64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz#9323c333924f97a02bdd2ae8912b36298acb312d" - integrity sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ== - esbuild-linux-arm@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.53.tgz#a44ec9b5b42007ab6c0d65a224ccc6bbd97c54cf" integrity sha512-/u81NGAVZMopbmzd21Nu/wvnKQK3pT4CrvQ8BTje1STXcQAGnfyKgQlj3m0j2BzYbvQxSy+TMck4TNV2onvoPA== -esbuild-linux-arm@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz#b407f47b3ae721fe4e00e19e9f19289bef87a111" - integrity sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ== - esbuild-linux-mips64le@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.53.tgz#a4d0b6b17cfdeea4e41b0b085a5f73d99311be9f" integrity sha512-d6/XHIQW714gSSp6tOOX2UscedVobELvQlPMkInhx1NPz4ThZI9uNLQ4qQJHGBGKGfu+rtJsxM4NVHLhnNRdWQ== -esbuild-linux-mips64le@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz#bdf905aae5c0bcaa8f83567fe4c4c1bdc1f14447" - integrity sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A== - esbuild-linux-ppc64le@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.53.tgz#8c331822c85465434e086e3e6065863770c38139" integrity sha512-ndnJmniKPCB52m+r6BtHHLAOXw+xBCWIxNnedbIpuREOcbSU/AlyM/2dA3BmUQhsHdb4w3amD5U2s91TJ3MzzA== -esbuild-linux-ppc64le@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz#2911eae1c90ff58a3bd3259cb557235df25aa3b4" - integrity sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA== - esbuild-linux-riscv64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.53.tgz#36fd75543401304bea8a2d63bf8ea18aaa508e00" integrity sha512-yG2sVH+QSix6ct4lIzJj329iJF3MhloLE6/vKMQAAd26UVPVkhMFqFopY+9kCgYsdeWvXdPgmyOuKa48Y7+/EQ== -esbuild-linux-riscv64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz#1837c660be12b1d20d2a29c7189ea703f93e9265" - integrity sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow== - esbuild-linux-s390x@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.53.tgz#1622677ab6824123f48f75d3afc031cd41936129" integrity sha512-OCJlgdkB+XPYndHmw6uZT7jcYgzmx9K+28PVdOa/eLjdoYkeAFvH5hTwX4AXGLZLH09tpl4bVsEtvuyUldaNCg== -esbuild-linux-s390x@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz#d52880ece229d1bd10b2d936b792914ffb07c7fc" - integrity sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag== - esbuild-netbsd-64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.53.tgz#e86d0efd0116658be335492ed12e66b26b4baf52" integrity sha512-gp2SB+Efc7MhMdWV2+pmIs/Ja/Mi5rjw+wlDmmbIn68VGXBleNgiEZG+eV2SRS0kJEUyHNedDtwRIMzaohWedQ== -esbuild-netbsd-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz#de14da46f1d20352b43e15d97a80a8788275e6ed" - integrity sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ== - esbuild-openbsd-64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.53.tgz#9bcbbe6f86304872c6e91f64c8eb73fc29c3588b" integrity sha512-eKQ30ZWe+WTZmteDYg8S+YjHV5s4iTxeSGhJKJajFfQx9TLZJvsJX0/paqwP51GicOUruFpSUAs2NCc0a4ivQQ== -esbuild-openbsd-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz#45e8a5fd74d92ad8f732c43582369c7990f5a0ac" - integrity sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w== - esbuild-sunos-64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.53.tgz#f7a872f7460bfb7b131f7188a95fbce3d1c577e8" integrity sha512-OWLpS7a2FrIRukQqcgQqR1XKn0jSJoOdT+RlhAxUoEQM/IpytS3FXzCJM6xjUYtpO5GMY0EdZJp+ur2pYdm39g== -esbuild-sunos-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz#f646ac3da7aac521ee0fdbc192750c87da697806" - integrity sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw== - esbuild-windows-32@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.53.tgz#c5e3ca50e2d1439cc2c9fe4defa63bcd474ce709" integrity sha512-m14XyWQP5rwGW0tbEfp95U6A0wY0DYPInWBB7D69FAXUpBpBObRoGTKRv36lf2RWOdE4YO3TNvj37zhXjVL5xg== -esbuild-windows-32@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz#fb4fe77c7591418880b3c9b5900adc4c094f2401" - integrity sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA== - esbuild-windows-64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.53.tgz#ec2ab4a60c5215f092ffe1eab6d01319e88238af" integrity sha512-s9skQFF0I7zqnQ2K8S1xdLSfZFsPLuOGmSx57h2btSEswv0N0YodYvqLcJMrNMXh6EynOmWD7rz+0rWWbFpIHQ== -esbuild-windows-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz#1fca8c654392c0c31bdaaed168becfea80e20660" - integrity sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ== - esbuild-windows-arm64@0.14.53: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.53.tgz#f71d403806bdf9f4a1f9d097db9aec949bd675c8" integrity sha512-E+5Gvb+ZWts+00T9II6wp2L3KG2r3iGxByqd/a1RmLmYWVsSVUjkvIxZuJ3hYTIbhLkH5PRwpldGTKYqVz0nzQ== -esbuild-windows-arm64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz#4ffd01b6b2888603f1584a2fe96b1f6a6f2b3dd8" - integrity sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg== - esbuild@^0.14.47: version "0.14.53" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.53.tgz#20b1007f686e8584f2a01a1bec5a37aac9498ce4" @@ -1664,33 +1664,33 @@ esbuild@^0.14.47: esbuild-windows-64 "0.14.53" esbuild-windows-arm64 "0.14.53" -esbuild@^0.15.9: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.13.tgz#7293480038feb2bafa91d3f6a20edab3ba6c108a" - integrity sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ== +esbuild@^0.16.3: + version "0.16.13" + resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.16.13.tgz#83cd347c28221268bbfa0425db532d7d05f85b48" + integrity sha512-oYwFdSEIoKM1oYzyem1osgKJAvg5447XF+05ava21fOtilyb2HeQQh26/74K4WeAk5dZmj/Mx10zUqUnI14jhA== optionalDependencies: - "@esbuild/android-arm" "0.15.13" - "@esbuild/linux-loong64" "0.15.13" - esbuild-android-64 "0.15.13" - esbuild-android-arm64 "0.15.13" - esbuild-darwin-64 "0.15.13" - esbuild-darwin-arm64 "0.15.13" - esbuild-freebsd-64 "0.15.13" - esbuild-freebsd-arm64 "0.15.13" - esbuild-linux-32 "0.15.13" - esbuild-linux-64 "0.15.13" - esbuild-linux-arm "0.15.13" - esbuild-linux-arm64 "0.15.13" - esbuild-linux-mips64le "0.15.13" - esbuild-linux-ppc64le "0.15.13" - esbuild-linux-riscv64 "0.15.13" - esbuild-linux-s390x "0.15.13" - esbuild-netbsd-64 "0.15.13" - esbuild-openbsd-64 "0.15.13" - esbuild-sunos-64 "0.15.13" - esbuild-windows-32 "0.15.13" - esbuild-windows-64 "0.15.13" - esbuild-windows-arm64 "0.15.13" + "@esbuild/android-arm" "0.16.13" + "@esbuild/android-arm64" "0.16.13" + "@esbuild/android-x64" "0.16.13" + "@esbuild/darwin-arm64" "0.16.13" + "@esbuild/darwin-x64" "0.16.13" + "@esbuild/freebsd-arm64" "0.16.13" + "@esbuild/freebsd-x64" "0.16.13" + "@esbuild/linux-arm" "0.16.13" + "@esbuild/linux-arm64" "0.16.13" + "@esbuild/linux-ia32" "0.16.13" + "@esbuild/linux-loong64" "0.16.13" + "@esbuild/linux-mips64el" "0.16.13" + "@esbuild/linux-ppc64" "0.16.13" + "@esbuild/linux-riscv64" "0.16.13" + "@esbuild/linux-s390x" "0.16.13" + "@esbuild/linux-x64" "0.16.13" + "@esbuild/netbsd-x64" "0.16.13" + "@esbuild/openbsd-x64" "0.16.13" + "@esbuild/sunos-x64" "0.16.13" + "@esbuild/win32-arm64" "0.16.13" + "@esbuild/win32-ia32" "0.16.13" + "@esbuild/win32-x64" "0.16.13" escalade@^3.1.1: version "3.1.1" @@ -2553,10 +2553,10 @@ postcss@^8.1.10, postcss@^8.2.9, postcss@^8.4.14: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8.4.18: - version "8.4.19" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.19.tgz#61178e2add236b17351897c8bcc0b4c8ecab56fc" - integrity sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA== +postcss@^8.4.20: + version "8.4.20" + resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.20.tgz#64c52f509644cecad8567e949f4081d98349dc56" + integrity sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g== dependencies: nanoid "^3.3.4" picocolors "^1.0.0" @@ -2642,10 +2642,10 @@ rollup@^2.75.6: optionalDependencies: fsevents "~2.3.2" -rollup@^2.79.1: - version "2.79.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" - integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== +rollup@^3.7.0: + version "3.9.1" + resolved "https://registry.npmmirror.com/rollup/-/rollup-3.9.1.tgz#27501d3d026418765fe379d5620d25954ff2a011" + integrity sha512-GswCYHXftN8ZKGVgQhTFUJB/NBXxrRGgO2NCy6E8s1rwEJ4Q9/VttNqcYfEvx4dTo4j58YqdC3OVztPzlKSX8w== optionalDependencies: fsevents "~2.3.2" @@ -2972,15 +2972,15 @@ vite@^3.0.4: optionalDependencies: fsevents "~2.3.2" -vite@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/vite/-/vite-3.2.3.tgz#7a68d9ef73eff7ee6dc0718ad3507adfc86944a7" - integrity sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ== +vite@^4.0.3: + version "4.0.3" + resolved "https://registry.npmmirror.com/vite/-/vite-4.0.3.tgz#de27ad3f263a03ae9419cdc8bc07721eadcba8b9" + integrity sha512-HvuNv1RdE7deIfQb8mPk51UKjqptO/4RXZ5yXSAvurd5xOckwS/gg8h9Tky3uSbnjYTgUm0hVCet1cyhKd73ZA== dependencies: - esbuild "^0.15.9" - postcss "^8.4.18" + esbuild "^0.16.3" + postcss "^8.4.20" resolve "^1.22.1" - rollup "^2.79.1" + rollup "^3.7.0" optionalDependencies: fsevents "~2.3.2" diff --git a/go.mod b/go.mod index 8509978aa..722eefd35 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.19 require ( github.com/creack/pty v1.1.18 github.com/dustin/go-humanize v1.0.0 - github.com/emirpasic/gods v1.18.1 github.com/gin-contrib/static v0.0.1 github.com/gin-gonic/gin v1.7.4 github.com/go-acme/lego/v4 v4.4.0 @@ -16,9 +15,11 @@ require ( github.com/golang-jwt/jwt v3.2.2+incompatible github.com/google/uuid v1.1.1 github.com/gorilla/websocket v1.4.2 + github.com/hpcloud/tail v1.0.0 github.com/pkg/errors v0.9.1 github.com/shirou/gopsutil/v3 v3.21.7 github.com/spf13/cast v1.3.1 + github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed github.com/unknwon/com v1.0.1 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad gopkg.in/ini.v1 v1.62.0 @@ -32,7 +33,6 @@ require ( github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-ole/go-ole v1.2.5 // indirect github.com/golang/protobuf v1.3.4 // indirect - github.com/hpcloud/tail v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.2 // indirect github.com/json-iterator/go v1.1.9 // indirect diff --git a/go.sum b/go.sum index 91bdb0b03..d8d0a3d98 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/0xJacky/gonginx v0.0.0-20230104051937-4c3a63627efb h1:UzbGgIvP2UXpqlPG0ylT8/y0TIl5tBvAIeI3OAChFHI= +github.com/0xJacky/gonginx v0.0.0-20230104051937-4c3a63627efb/go.mod h1:+uQMU+LMBHOQermcm/ICplG+r35Ypb6Up9iYKlvKuTE= github.com/Azure/azure-sdk-for-go v32.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= @@ -97,14 +99,13 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= -github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/exoscale/egoscale v0.46.0/go.mod h1:mpEXBpROAa/2i5GC0r33rfxG+TxSEka11g1PIXt9+zc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/getkin/kin-openapi v0.13.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -172,8 +173,10 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -429,6 +432,8 @@ github.com/tklauser/numcpus v0.2.3 h1:nQ0QYpiritP6ViFhrKYsiv6VVxOpum2Gks5GhnJbS/ github.com/tklauser/numcpus v0.2.3/go.mod h1:vpEPS/JC+oZGGQ/My/vJnNsvMDQL6PwOqt8dsCw5j+E= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g= +github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed h1:EyT9V+boG4nI4pzIuN4AWHQNvyM1LxNS21MC1CDSfg4= +github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed/go.mod h1:+uQMU+LMBHOQermcm/ICplG+r35Ypb6Up9iYKlvKuTE= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= @@ -446,6 +451,7 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -502,6 +508,7 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -529,6 +536,7 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d h1:1aflnvSoWWLI2k/dMUAl5lvU1YO4Mb4hz0gh+1rjcxU= golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -543,6 +551,7 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -589,6 +598,7 @@ golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -641,9 +651,11 @@ golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -725,6 +737,8 @@ gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9D gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.21.14 h1:NAR9A/3SoyiPVHouW/rlpMUZvuQZ6Z6UYGz+2tosSQo= gorm.io/gorm v1.21.14/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I= +gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/server/api/cert.go b/server/api/cert.go index 201c57ef5..5a2c8cb10 100644 --- a/server/api/cert.go +++ b/server/api/cert.go @@ -1,140 +1,352 @@ 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" + "github.com/spf13/cast" + "log" + "net/http" + "os" + "path/filepath" + "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 + }, + } - 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 + } - // 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) - 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"` + } - // read - mt, message, err := ws.ReadMessage() + err = ws.ReadJSON(&buffer) - if err != nil { - log.Println(err) - return - } + 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) - logChan := make(chan string, 1) - errChan := make(chan error, 1) + go cert.IssueCert(buffer.ServerName, logChan, errChan) - go cert.IssueCert(domain, logChan, errChan) + domain := strings.Join(buffer.ServerName, "_") - go handleIssueCertLogChan(ws, logChan) + go handleIssueCertLogChan(ws, logChan) - // block, unless errChan closed - for err = range errChan { - log.Println("Error cert.IssueCert", err) + // block, unless errChan closed + for err = range errChan { + log.Println("Error cert.IssueCert", err) - err = ws.WriteJSON(IssueCertResponse{ - Status: Error, - Message: err.Error(), - }) + err = ws.WriteJSON(IssueCertResponse{ + Status: Error, + Message: err.Error(), + }) - if err != nil { - log.Println(err) - return - } + if err != nil { + log.Println("Error WriteJSON", err) + return + } - return - } + return + } - close(logChan) + close(logChan) - sslCertificatePath := nginx.GetNginxConfPath("ssl/" + domain + "/fullchain.cer") - sslCertificateKeyPath := nginx.GetNginxConfPath("ssl/" + domain + "/" + domain + ".key") + sslCertificatePath := nginx.GetNginxConfPath("ssl/" + domain + "/fullchain.cer") + sslCertificateKeyPath := nginx.GetNginxConfPath("ssl/" + domain + "/private.key") - certModel, err := model.FirstCert(domain) + certModel, err := model.FirstOrCreateCert(domain) - if err != nil { - log.Println(err) - return - } + if err != nil { + log.Println(err) + } - err = certModel.Updates(&model.Cert{ - SSLCertificatePath: sslCertificatePath, - }) + err = certModel.Updates(&model.Cert{ + SSLCertificatePath: sslCertificatePath, + SSLCertificateKeyPath: sslCertificateKeyPath, + }) - if err != nil { - log.Println(err) - return - } + if err != nil { + log.Println(err) + } - err = ws.WriteJSON(IssueCertResponse{ - Status: Success, - Message: "Issued certificate successfully", - SSLCertificate: sslCertificatePath, - SSLCertificateKey: sslCertificateKeyPath, - }) + err = ws.WriteJSON(IssueCertResponse{ + Status: Success, + Message: "Issued certificate successfully", + SSLCertificate: sslCertificatePath, + SSLCertificateKey: sslCertificateKeyPath, + }) - if err != nil { - log.Println(err) - return - } + if err != nil { + log.Println(err) + return + } } + +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 model.Cert) { + type resp struct { + model.Cert + SSLCertification string `json:"ssl_certification"` + SSLCertificationKey string `json:"ssl_certification_key"` + CertificateInfo *CertificateInfo `json:"certificate_info,omitempty"` + } + + var sslCertificationBytes, sslCertificationKeyBytes []byte + var certificateInfo *CertificateInfo + if certModel.SSLCertificatePath != "" { + if _, err := os.Stat(certModel.SSLCertificatePath); err == nil { + sslCertificationBytes, _ = os.ReadFile(certModel.SSLCertificatePath) + } + + pubKey, err := cert.GetCertInfo(certModel.SSLCertificatePath) + + if err != nil { + ErrHandler(c, err) + return + } + + certificateInfo = &CertificateInfo{ + SubjectName: pubKey.Subject.CommonName, + IssuerName: pubKey.Issuer.CommonName, + NotAfter: pubKey.NotAfter, + NotBefore: pubKey.NotBefore, + } + } + + if certModel.SSLCertificateKeyPath != "" { + if _, err := os.Stat(certModel.SSLCertificateKeyPath); err == nil { + sslCertificationKeyBytes, _ = os.ReadFile(certModel.SSLCertificateKeyPath) + } + } + + c.JSON(http.StatusOK, resp{ + certModel, + string(sslCertificationBytes), + string(sslCertificationKeyBytes), + certificateInfo, + }) +} + +func GetCert(c *gin.Context) { + certModel, err := model.FirstCertByID(cast.ToInt(c.Param("id"))) + + if err != nil { + ErrHandler(c, err) + return + } + + getCert(c, certModel) +} + +func AddCert(c *gin.Context) { + var json struct { + Name string `json:"name"` + Domain string `json:"domain" binding:"required"` + SSLCertificatePath string `json:"ssl_certificate_path" binding:"required"` + SSLCertificateKeyPath string `json:"ssl_certificate_key_path" binding:"required"` + SSLCertification string `json:"ssl_certification"` + SSLCertificationKey string `json:"ssl_certification_key"` + } + 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 + } + + err = os.MkdirAll(filepath.Dir(json.SSLCertificatePath), 0644) + if err != nil { + ErrHandler(c, err) + return + } + + err = os.MkdirAll(filepath.Dir(json.SSLCertificateKeyPath), 0644) + if err != nil { + ErrHandler(c, err) + return + } + + if json.SSLCertification != "" { + err = os.WriteFile(json.SSLCertificatePath, []byte(json.SSLCertification), 0644) + if err != nil { + ErrHandler(c, err) + return + } + } + + if json.SSLCertificationKey != "" { + err = os.WriteFile(json.SSLCertificateKeyPath, []byte(json.SSLCertificationKey), 0644) + if err != nil { + ErrHandler(c, err) + return + } + } + + getCert(c, certModel) +} + +func ModifyCert(c *gin.Context) { + id := cast.ToInt(c.Param("id")) + certModel, err := model.FirstCertByID(id) + + var json struct { + Name string `json:"name"` + Domain string `json:"domain" binding:"required"` + SSLCertificatePath string `json:"ssl_certificate_path" binding:"required"` + SSLCertificateKeyPath string `json:"ssl_certificate_key_path" binding:"required"` + SSLCertification string `json:"ssl_certification"` + SSLCertificationKey string `json:"ssl_certification_key"` + } + + 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 + } + + err = os.MkdirAll(filepath.Dir(json.SSLCertificatePath), 0644) + if err != nil { + ErrHandler(c, err) + return + } + + err = os.MkdirAll(filepath.Dir(json.SSLCertificateKeyPath), 0644) + if err != nil { + ErrHandler(c, err) + return + } + + if json.SSLCertification != "" { + err = os.WriteFile(json.SSLCertificatePath, []byte(json.SSLCertification), 0644) + if err != nil { + ErrHandler(c, err) + return + } + } + + if json.SSLCertificationKey != "" { + err = os.WriteFile(json.SSLCertificateKeyPath, []byte(json.SSLCertificationKey), 0644) + if err != nil { + ErrHandler(c, err) + return + } + } + + GetCert(c) +} + +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.StatusNoContent, nil) +} diff --git a/server/api/config.go b/server/api/config.go index cd2e395aa..062e3d681 100644 --- a/server/api/config.go +++ b/server/api/config.go @@ -14,13 +14,15 @@ import ( func GetConfigs(c *gin.Context) { 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("/")) + configFiles, err := os.ReadDir(nginx.GetNginxConfPath(dir)) if err != nil { ErrHandler(c, err) @@ -56,14 +58,13 @@ func GetConfigs(c *gin.Context) { if targetInfo.IsDir() { continue } - default: - continue } configs = append(configs, gin.H{ "name": file.Name(), "size": fileInfo.Size(), "modify": fileInfo.ModTime(), + "is_dir": file.IsDir(), }) } @@ -109,7 +110,6 @@ func AddConfig(c *gin.Context) { 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", diff --git a/server/api/domain.go b/server/api/domain.go index 9307bc33f..19a0c2649 100644 --- a/server/api/domain.go +++ b/server/api/domain.go @@ -77,7 +77,15 @@ type CertificateInfo struct { } func GetDomain(c *gin.Context) { + rewriteName, ok := c.Get("rewriteConfigFileName") + name := c.Param("name") + + // for modify filename + if ok { + name = rewriteName.(string) + } + path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name) enabled := true @@ -93,8 +101,15 @@ func GetDomain(c *gin.Context) { } 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 == "ssl_certificate" { pubKey, err := cert.GetCertInfo(directive.Params) @@ -116,33 +131,73 @@ func GetDomain(c *gin.Context) { } } - _, err = model.FirstCert(name) + certModel, _ := model.FirstCert(serverName) c.JSON(http.StatusOK, gin.H{ "enabled": enabled, "name": name, - "config": config.BuildConfig(), + "config": config.FmtCode(), "tokenized": config, - "auto_cert": err == nil, + "auto_cert": certModel.AutoCert == model.AutoCertEnabled, "cert_info": certInfoMap, }) } func EditDomain(c *gin.Context) { - var err error name := c.Param("name") - request := make(gin.H) - err = c.BindJSON(&request) + + 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(request["content"].(string)), 0644) + 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() @@ -287,20 +342,36 @@ func DeleteDomain(c *gin.Context) { func AddDomainToAutoCert(c *gin.Context) { 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) { + domain := c.Param("domain") + domain = strings.ReplaceAll(domain, " ", "_") certModel := model.Cert{ - Domain: c.Param("domain"), + Domain: domain, } - err := certModel.Remove() + + err := certModel.Updates(&model.Cert{ + AutoCert: model.AutoCertDisabled, + }) if err != nil { ErrHandler(c, err) diff --git a/server/api/nginx_log.go b/server/api/nginx_log.go index f7f030967..c6ec32d70 100644 --- a/server/api/nginx_log.go +++ b/server/api/nginx_log.go @@ -125,7 +125,6 @@ func getLogPath(control *controlStruct) (logPath string, err error) { } directive := config.Servers[control.ServerIdx].Directives[control.DirectiveIdx] - switch directive.Directive { case "access_log", "error_log": // ok diff --git a/server/api/ngx.go b/server/api/ngx.go index 9cef7daf9..76c700b4d 100644 --- a/server/api/ngx.go +++ b/server/api/ngx.go @@ -1,42 +1,47 @@ package api import ( - "bufio" - nginx2 "github.com/0xJacky/Nginx-UI/server/pkg/nginx" - "github.com/gin-gonic/gin" - "net/http" - "strings" + "github.com/0xJacky/Nginx-UI/server/pkg/nginx" + "github.com/gin-gonic/gin" + "net/http" ) func BuildNginxConfig(c *gin.Context) { - var ngxConf nginx2.NgxConfig - if !BindAndValid(c, &ngxConf) { - return - } - - c.JSON(http.StatusOK, gin.H{ - "content": ngxConf.BuildConfig(), - }) + var ngxConf nginx.NgxConfig + if !BindAndValid(c, &ngxConf) { + return + } + + c.JSON(http.StatusOK, gin.H{ + "content": ngxConf.BuildConfig(), + }) } func TokenizeNginxConfig(c *gin.Context) { - var json struct { - Content string `json:"content" binding:"required"` - } + var json struct { + Content string `json:"content" binding:"required"` + } - if !BindAndValid(c, &json) { - return - } + if !BindAndValid(c, &json) { + return + } - scanner := bufio.NewScanner(strings.NewReader(json.Content)) + ngxConfig := nginx.ParseNgxConfigByContent(json.Content) - ngxConfig, err := nginx2.ParseNgxConfigByScanner("", scanner) + c.JSON(http.StatusOK, ngxConfig) - if err != nil { - ErrHandler(c, err) - return - } +} + +func FormatNginxConfig(c *gin.Context) { + var json struct { + Content string `json:"content" binding:"required"` + } - c.JSON(http.StatusOK, ngxConfig) + if !BindAndValid(c, &json) { + return + } + c.JSON(http.StatusOK, gin.H{ + "content": nginx.FmtCode(json.Content), + }) } 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/api/template.go b/server/api/template.go index c7b5a5cbf..cf9899e9a 100644 --- a/server/api/template.go +++ b/server/api/template.go @@ -2,6 +2,7 @@ package api import ( "github.com/0xJacky/Nginx-UI/server/pkg/nginx" + "github.com/0xJacky/Nginx-UI/server/service" "github.com/0xJacky/Nginx-UI/server/settings" "github.com/gin-gonic/gin" "net/http" @@ -57,3 +58,45 @@ proxy_pass http://127.0.0.1:{{ HTTP01PORT }}; "tokenized": ngxConfig, }) } + +func GetTemplateConfList(c *gin.Context) { + configList, err := service.GetTemplateList("conf") + + if err != nil { + ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, gin.H{ + "data": configList, + }) +} + +func GetTemplateBlockList(c *gin.Context) { + configList, err := service.GetTemplateList("block") + + if err != nil { + ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, gin.H{ + "data": configList, + }) +} + +func GetTemplateBlock(c *gin.Context) { + type resp struct { + service.ConfigInfoItem + service.ConfigDetail + } + detail, err := service.ParseTemplate("block", c.Param("name")) + if err != nil { + ErrHandler(c, err) + return + } + c.JSON(http.StatusOK, resp{ + service.GetTemplateInfo("block", c.Param("name")), + detail, + }) +} 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/pkg/cert/auto_cert.go b/server/pkg/cert/auto_cert.go index 0ba8a171f..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(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 de2fbd5c8..8dc260c20 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) @@ -62,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" @@ -94,7 +99,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 +109,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 +131,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, "private.key"), certificates.PrivateKey, 0644) if err != nil { diff --git a/server/pkg/nginx/build_config.go b/server/pkg/nginx/build_config.go index 7eecb5df5..dd434dd2d 100644 --- a/server/pkg/nginx/build_config.go +++ b/server/pkg/nginx/build_config.go @@ -1,88 +1,90 @@ package nginx import ( - "bufio" - "fmt" - "strings" + "bufio" + "fmt" + "github.com/tufanbarisyildirim/gonginx" + "github.com/tufanbarisyildirim/gonginx/parser" + "strings" ) func buildComments(orig string, indent int) (content string) { - scanner := bufio.NewScanner(strings.NewReader(orig)) - for scanner.Scan() { - content += strings.Repeat("\t", indent) + "# " + scanner.Text() + "\n" - } - content = strings.TrimLeft(content, "\n") - return + scanner := bufio.NewScanner(strings.NewReader(orig)) + for scanner.Scan() { + content += strings.Repeat("\t", indent) + "# " + scanner.Text() + "\n" + } + content = strings.TrimLeft(content, "\n") + return } func (c *NgxConfig) BuildConfig() (content string) { - // Custom - if c.Custom != "" { - content += fmtCode(c.Custom) - content += "\n\n" - } + // Custom + if c.Custom != "" { + content += c.Custom + content += "\n\n" + } - // Upstreams - for _, u := range c.Upstreams { + // Upstreams + for _, u := range c.Upstreams { - upstream := "" - var comments string - for _, directive := range u.Directives { - if directive.Comments != "" { - comments = buildComments(directive.Comments, 1) - } - upstream += fmt.Sprintf("%s\t%s;\n", comments, directive.Orig()) - } - comments = buildComments(u.Comments, 1) - content += fmt.Sprintf("upstream %s {\n%s%s}\n\n", u.Name, comments, upstream) - } + upstream := "" + var comments string + for _, directive := range u.Directives { + if directive.Comments != "" { + comments = buildComments(directive.Comments, 1) + } + upstream += fmt.Sprintf("%s\t%s;\n", comments, directive.Orig()) + } + comments = buildComments(u.Comments, 1) + content += fmt.Sprintf("upstream %s {\n%s%s}\n\n", u.Name, comments, upstream) + } - // Servers - for _, s := range c.Servers { - server := "" + // Servers + for _, s := range c.Servers { + server := "" - // directives - for _, directive := range s.Directives { - var comments string - if directive.Comments != "" { - comments = buildComments(directive.Comments, 1) - } - if directive.Directive == If { - server += fmt.Sprintf("%s%s\n", comments, fmtCodeWithIndent(directive.Params, 1)) - } else if directive.Params != "" { - server += fmt.Sprintf("%s\t%s;\n", comments, directive.Orig()) - } - } + // directives + for _, directive := range s.Directives { + var comments string + if directive.Comments != "" { + comments = buildComments(directive.Comments, 1) + } + if directive.Params != "" { + server += fmt.Sprintf("%s\t%s;\n", comments, directive.Orig()) + } + } - if len(s.Directives) > 0 { - server += "\n" - } + if len(s.Directives) > 0 { + server += "\n" + } - // locations - locations := "" - for _, location := range s.Locations { - locationContent := "" - scanner := bufio.NewScanner(strings.NewReader(location.Content)) - for scanner.Scan() { - locationContent += "\t\t" + scanner.Text() + "\n" - } - var comments string - if location.Comments != "" { - comments = buildComments(location.Comments, 1) - } - locations += fmt.Sprintf("%s\tlocation %s {\n%s\t}\n\n", comments, location.Path, locationContent) - } + // locations + locations := "" + for _, location := range s.Locations { + locationContent := "" + scanner := bufio.NewScanner(strings.NewReader(location.Content)) + for scanner.Scan() { + locationContent += "\t\t" + scanner.Text() + "\n" + } + var comments string + if location.Comments != "" { + comments = buildComments(location.Comments, 1) + } + locations += fmt.Sprintf("%s\tlocation %s {\n%s\t}\n\n", comments, location.Path, locationContent) + } - server += locations + server += locations - var comments string - if s.Comments != "" { - comments = buildComments(s.Comments, 0) + "\n" - } + var comments string + if s.Comments != "" { + comments = buildComments(s.Comments, 0) + "\n" + } - content += fmt.Sprintf("%sserver {\n%s}\n\n", comments, server) - } - - return + content += fmt.Sprintf("%sserver {\n%s}\n\n", comments, server) + } + p := parser.NewStringParser(content) + config := p.Parse() + content = gonginx.DumpConfig(config, gonginx.IndentedStyle) + return } diff --git a/server/test/nextcloud_ngx.conf b/server/pkg/nginx/conf/nextcloud_ngx.conf similarity index 100% rename from server/test/nextcloud_ngx.conf rename to server/pkg/nginx/conf/nextcloud_ngx.conf diff --git a/server/pkg/nginx/conf/test.conf b/server/pkg/nginx/conf/test.conf new file mode 100644 index 000000000..2df9ca326 --- /dev/null +++ b/server/pkg/nginx/conf/test.conf @@ -0,0 +1,36 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 80; + listen [::]:80; + server_name blog.jackyu.cn test.jackyu.cn; + + location /.well-known/acme-challenge { + proxy_set_header Host $host; + proxy_set_header X-Real_IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr:$remote_port; + proxy_pass http://127.0.0.1:9180; + } + +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name blog.jackyu.cn test.jackyu.cn; + ssl_certificate /etc/nginx/ssl/blog.jackyu.cn_test.jackyu.cn/fullchain.cer; + ssl_certificate_key /etc/nginx/ssl/blog.jackyu.cn_test.jackyu.cn/private.key; + include enable-php-8.conf; + + location /.well-known/acme-challenge { + proxy_set_header Host $host; + proxy_set_header X-Real_IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr:$remote_port; + proxy_pass http://127.0.0.1:9180; + } + +} + diff --git a/server/pkg/nginx/format_code.go b/server/pkg/nginx/format_code.go index bf80aeafd..08f81f7b5 100644 --- a/server/pkg/nginx/format_code.go +++ b/server/pkg/nginx/format_code.go @@ -1,49 +1,18 @@ package nginx import ( - "bufio" - "github.com/emirpasic/gods/stacks/linkedliststack" - "strings" + "github.com/tufanbarisyildirim/gonginx" + "github.com/tufanbarisyildirim/gonginx/parser" ) -func fmtCode(content string) (fmtContent string) { - fmtContent = fmtCodeWithIndent(content, 0) - return +func (c *NgxConfig) FmtCode() (fmtContent string) { + fmtContent = gonginx.DumpConfig(c.c, gonginx.IndentedStyle) + return } -func fmtCodeWithIndent(content string, indent int) (fmtContent string) { - /* - Format content - 1. TrimSpace for each line - 2. use stack to count how many \t should add - */ - stack := linkedliststack.New() - - scanner := bufio.NewScanner(strings.NewReader(content)) - - for scanner.Scan() { - text := scanner.Text() - text = strings.TrimSpace(text) - - before := stack.Size() - - for _, char := range text { - matchParentheses(stack, char) - } - - after := stack.Size() - - fmtContent += strings.Repeat("\t", indent) - - if before == after { - fmtContent += strings.Repeat("\t", stack.Size()) + text + "\n" - } else { - fmtContent += text + "\n" - } - - } - - fmtContent = strings.Trim(fmtContent, "\n") - - return +func FmtCode(content string) (fmtContent string) { + p := parser.NewStringParser(content) + c := p.Parse() + fmtContent = gonginx.DumpConfig(c, gonginx.IndentedStyle) + return } diff --git a/server/pkg/nginx/ngx_conf_parse_test.go b/server/pkg/nginx/ngx_conf_parse_test.go new file mode 100644 index 000000000..b4782fc5a --- /dev/null +++ b/server/pkg/nginx/ngx_conf_parse_test.go @@ -0,0 +1,49 @@ +package nginx + +import ( + "fmt" + "github.com/tufanbarisyildirim/gonginx" + "github.com/tufanbarisyildirim/gonginx/parser" + "strings" + "testing" +) + +func TestNgxConfParse(t *testing.T) { + p, err := parser.NewParser("conf/nextcloud_ngx.conf") + if err != nil { + fmt.Println(err) + return + } + n := p.Parse() + + fn(n.Block, 0) + + c, err := ParseNgxConfig("conf/nextcloud_ngx.conf") + if err != nil { + fmt.Println(err) + return + } + fmt.Println(c) + c, err = ParseNgxConfig("conf/test.conf") + if err != nil { + fmt.Println(err) + return + } + fmt.Println(c) +} + +func fn(block gonginx.IBlock, deep int) { + if block == nil { + return + } + for _, v := range block.GetDirectives() { + if len(v.GetComment()) > 0 { + for _, c := range v.GetComment() { + fmt.Println(strings.Repeat("\t", deep), c) + } + } + + fmt.Println(fmt.Sprintf("%s%s %s", strings.Repeat("\t", deep), v.GetName(), strings.Join(v.GetParameters(), " "))) + fn(v.GetBlock(), deep+1) + } +} diff --git a/server/pkg/nginx/parse.go b/server/pkg/nginx/parse.go index a8e490704..39d2e454c 100644 --- a/server/pkg/nginx/parse.go +++ b/server/pkg/nginx/parse.go @@ -1,150 +1,169 @@ package nginx import ( - "bufio" - "github.com/emirpasic/gods/stacks/linkedliststack" "github.com/pkg/errors" - "os" + "github.com/tufanbarisyildirim/gonginx" + "github.com/tufanbarisyildirim/gonginx/parser" "strings" - "unicode" ) const ( - Server = "server" - Location = "location" - Upstream = "upstream" - CommentStart = "#" - Empty = "" - If = "if" + Server = "server" + Location = "location" + Upstream = "upstream" ) -func matchParentheses(stack *linkedliststack.Stack, v int32) { - if v == '{' { - stack.Push(v) - } else if v == '}' { - // stack is not empty and the top is == '{' - if top, ok := stack.Peek(); ok && top == '{' { - stack.Pop() - } else { - // fail - stack.Push(v) - } - } +func (s *NgxServer) ParseServer(directive gonginx.IDirective) { + s.parseServer(directive) } -func parseDirective(scanner *bufio.Scanner) (d NgxDirective) { - text := strings.TrimSpace(scanner.Text()) - // escape empty line or comment line - if len(text) < 1 { +func (s *NgxServer) parseServer(directive gonginx.IDirective) { + if directive.GetBlock() == nil { return } - - if text[0] == '#' { - d.Directive = "#" - d.Params = strings.TrimLeft(text, "#") + for _, d := range directive.GetBlock().GetDirectives() { + switch d.GetName() { + case Location: + location := &NgxLocation{ + Path: strings.Join(d.GetParameters(), " "), + Comments: buildComment(d.GetComment()), + } + location.parseLocation(d, 0) + s.Locations = append(s.Locations, location) + default: + dir := &NgxDirective{ + Directive: d.GetName(), + Comments: buildComment(d.GetComment()), + } + dir.parseDirective(d, 0) + s.Directives = append(s.Directives, dir) + } + } +} +func (l *NgxLocation) ParseLocation(directive gonginx.IDirective, deep int) { + l.parseLocation(directive, deep) +} +func (l *NgxLocation) parseLocation(directive gonginx.IDirective, deep int) { + if directive.GetBlock() == nil { return } - - if len(text) > 1 { - sep := len(text) - 1 - for k, v := range text { - if unicode.IsSpace(v) { - sep = k - break + for _, location := range directive.GetBlock().GetDirectives() { + if len(location.GetComment()) > 0 { + for _, c := range location.GetComment() { + l.Content += strings.Repeat("\t", deep) + c + "\n" } } - - d.Directive = text[0:sep] - d.Params = text[sep:] - } else { - d.Directive = text - return + l.Content += strings.Repeat("\t", deep) + location.GetName() + " " + strings.Join(location.GetParameters(), " ") + ";\n" + l.parseLocation(location, deep+1) } +} - stack := linkedliststack.New() - - if d.Directive == Server || d.Directive == Upstream || d.Directive == Location || d.Directive == If { - // { } in one line - // location = /.well-known/carddav { return 301 /remote.php/dav/; } - if strings.Contains(d.Params, "{") { - for _, v := range d.Params { - matchParentheses(stack, v) - } +func (d *NgxDirective) ParseDirective(directive gonginx.IDirective, deep int) { + d.parseDirective(directive, deep) +} - if stack.Empty() { - return +func (d *NgxDirective) parseDirective(directive gonginx.IDirective, deep int) { + if directive.GetBlock() != nil { + d.Params += directive.GetName() + " " + d.Directive = "" + } + d.Params += strings.Join(directive.GetParameters(), " ") + if directive.GetBlock() != nil { + d.Params += " {\n" + for _, location := range directive.GetBlock().GetDirectives() { + if len(location.GetComment()) > 0 { + for _, c := range location.GetComment() { + d.Params += strings.Repeat("\t", deep) + c + "\n" + } } - } - - // location ^~ /.well-known { - // location ^~ /.well-known - // { - // location ^~ /.well-known - // - // { - // { } not in one line - for scanner.Scan() { - text = strings.TrimSpace(scanner.Text()) - // escape empty line - if text == "" { + d.Params += strings.Repeat("\t", deep+1) + location.GetName() + " " + + strings.Join(location.GetParameters(), " ") + ";\n" + // d.parseDirective(location, deep+1) + if location.GetBlock() == nil { continue } - d.Params += "\n" + scanner.Text() - for _, v := range text { - matchParentheses(stack, v) - if stack.Empty() { - break - } - } - if stack.Empty() { - break + for _, v := range location.GetBlock().GetDirectives() { + d.parseDirective(v, deep+1) } } + d.Params += "}\n" + return + } +} + +func (u *NgxUpstream) parseUpstream(directive gonginx.IDirective) { + if directive.GetBlock() == nil { + return + } + for _, us := range directive.GetBlock().GetDirectives() { + d := &NgxDirective{ + Directive: us.GetName(), + Params: strings.Join(us.GetParameters(), " "), + Comments: buildComment(us.GetComment()), + } + u.Directives = append(u.Directives, d) } - d.Params = strings.TrimSpace(d.Params) - return } -func ParseNgxConfigByScanner(filename string, scanner *bufio.Scanner) (c *NgxConfig, err error) { - c = NewNgxConfig(filename) +func (c *NgxConfig) parseCustom(directive gonginx.IDirective) { + if directive.GetBlock() == nil { + return + } + c.Custom += "{\n" + for _, v := range directive.GetBlock().GetDirectives() { + c.Custom += strings.Join(v.GetComment(), "\n") + "\n" + + v.GetName() + " " + strings.Join(v.GetParameters(), " ") + ";\n" + } + c.Custom += "}\n" +} + +func buildComment(c []string) string { + return strings.ReplaceAll(strings.Join(c, "\n"), "#", "") +} - for scanner.Scan() { - d := parseDirective(scanner) - paramsScanner := bufio.NewScanner(strings.NewReader(d.Params)) - switch d.Directive { +func parse(block gonginx.IBlock, ngxConfig *NgxConfig) { + if block == nil { + return + } + for _, v := range block.GetDirectives() { + comments := buildComment(v.GetComment()) + switch v.GetName() { case Server: - c.parseServer(paramsScanner) + server := NewNgxServer() + server.Comments = comments + server.parseServer(v) + ngxConfig.Servers = append(ngxConfig.Servers, server) case Upstream: - c.parseUpstream(paramsScanner) - case CommentStart: - c.commentQueue.Enqueue(d.Params) - case Empty: - continue + upstream := &NgxUpstream{} + upstream.Comments = comments + upstream.parseUpstream(v) + ngxConfig.Upstreams = append(ngxConfig.Upstreams, upstream) default: - c.Custom += d.Orig() + "\n" + ngxConfig.Custom += strings.Join(v.GetComment(), "\n") + "\n" + + v.GetName() + " " + strings.Join(v.GetParameters(), " ") + "\n" + ngxConfig.parseCustom(v) } } + ngxConfig.Custom = FmtCode(ngxConfig.Custom) +} - if err = scanner.Err(); err != nil { - return nil, errors.Wrap(err, "error scanner in ParseNgxConfig") - } - - // Attach the rest of the comments to the last server - if len(c.Servers) > 0 { - c.Servers[len(c.Servers)-1].Comments += c.commentQueue.DequeueAllComments() - } - - return c, nil +func ParseNgxConfigByContent(content string) (ngxConfig *NgxConfig) { + p := parser.NewStringParser(content) + c := p.Parse() + ngxConfig = NewNgxConfig("") + ngxConfig.c = c + parse(c.Block, ngxConfig) + return } -func ParseNgxConfig(filename string) (c *NgxConfig, err error) { - file, err := os.Open(filename) +func ParseNgxConfig(filename string) (ngxConfig *NgxConfig, err error) { + p, err := parser.NewParser(filename) if err != nil { - return nil, errors.Wrap(err, "error open file in ParseNgxConfig") + return nil, errors.Wrap(err, "error ParseNgxConfig") } - defer file.Close() - - scanner := bufio.NewScanner(file) - - return ParseNgxConfigByScanner(filename, scanner) + c := p.Parse() + ngxConfig = NewNgxConfig(filename) + ngxConfig.c = c + parse(c.Block, ngxConfig) + return } diff --git a/server/pkg/nginx/tokenize.go b/server/pkg/nginx/tokenize.go deleted file mode 100644 index e8a634233..000000000 --- a/server/pkg/nginx/tokenize.go +++ /dev/null @@ -1,125 +0,0 @@ -package nginx - -import ( - "bufio" - "regexp" - "strings" - "unicode" -) - -func (c *NgxConfig) parseServer(scanner *bufio.Scanner) { - server := NewNgxServer() - for scanner.Scan() { - d := parseDirective(scanner) - switch d.Directive { - case Location: - server.parseLocation(d.Params) - case CommentStart: - server.commentQueue.Enqueue(d.Params) - default: - server.parseDirective(d) - } - } - // Attach the rest of the comments to the last location - if len(server.Locations) > 0 { - server.Locations[len(server.Locations)-1].Comments += server.commentQueue.DequeueAllComments() - } - - // Attach comments which are over the current server - server.Comments = c.commentQueue.DequeueAllComments() - - c.Servers = append(c.Servers, server) -} - -func (c *NgxConfig) parseUpstream(scanner *bufio.Scanner) { - upstream := &NgxUpstream{} - for scanner.Scan() { - d := NgxDirective{} - text := strings.TrimSpace(scanner.Text()) - // escape empty line or comment line - if len(text) < 1 || text[0] == '#' { - return - } - - sep := len(text) - 1 - for k, v := range text { - if unicode.IsSpace(v) { - sep = k - break - } - } - - d.Directive = text[0:sep] - d.Params = strings.Trim(text[sep:], ";") - - if d.Directive == Server { - upstream.Directives = append(upstream.Directives, &d) - } else if upstream.Name == "" { - upstream.Name = d.Directive - } - } - // attach comments which are over the current upstream - upstream.Comments = c.commentQueue.DequeueAllComments() - - c.Upstreams = append(c.Upstreams, upstream) -} - -func (s *NgxServer) parseDirective(d NgxDirective) { - orig := d.Orig() - // handle inline comments - str, comments, _ := strings.Cut(orig, "#") - - if d.Directive == If { - d.Params = "if " + d.Params - d.Params = fmtCode(d.Params) - s.Directives = append(s.Directives, &d) - return - } - - regExp := regexp.MustCompile("(\\S+?)\\s+?{?(.+?)[;|}]") - matchSlice := regExp.FindAllStringSubmatch(str, -1) - - for k, v := range matchSlice { - // [[gzip_min_length 256; gzip_min_length 256] [gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; gzip_proxied expired no-cache no-store private no_last_modified no_etag auth] [gzip on; gzip on] [gzip_vary on; gzip_vary on] [location /x/ {} location /x/ {] [gzip_comp_level 4; gzip_comp_level 4]] - if len(v) > 0 { - scanner := bufio.NewScanner(strings.NewReader(v[0])) - if scanner.Scan() { - d = parseDirective(scanner) - // inline location - if d.Directive == Location { - s.parseLocation(d.Orig()) - } else { - - if k == 0 { - d.Comments = s.commentQueue.DequeueAllComments() - } else if k == len(matchSlice)-1 { - d.Comments = comments - } - - // trim right ';' - d.TrimParams() - // map[directive]=>[]Params - s.Directives = append(s.Directives, &d) - } - - } - } - } -} - -func (s *NgxServer) parseLocation(str string) { - path, content, _ := strings.Cut(str, "{") - path = strings.TrimSpace(path) - - content = strings.TrimSpace(content) - content = strings.Trim(content, "}") - - content = fmtCode(content) - - location := &NgxLocation{ - Path: path, - Content: content, - } - location.Comments = s.commentQueue.DequeueAllComments() - s.Locations = append(s.Locations, location) -} diff --git a/server/pkg/nginx/type.go b/server/pkg/nginx/type.go index 3a7186dda..cf803e067 100644 --- a/server/pkg/nginx/type.go +++ b/server/pkg/nginx/type.go @@ -1,27 +1,22 @@ package nginx import ( - "github.com/emirpasic/gods/queues/linkedlistqueue" + "github.com/tufanbarisyildirim/gonginx" "strings" ) -type CommentQueue struct { - *linkedlistqueue.Queue -} - type NgxConfig struct { - FileName string `json:"file_name"` - Upstreams []*NgxUpstream `json:"upstreams"` - Servers []*NgxServer `json:"servers"` - Custom string `json:"custom"` - commentQueue *CommentQueue + FileName string `json:"file_name"` + Upstreams []*NgxUpstream `json:"upstreams"` + Servers []*NgxServer `json:"servers"` + Custom string `json:"custom"` + c *gonginx.Config } type NgxServer struct { - Directives []*NgxDirective `json:"directives"` - Locations []*NgxLocation `json:"locations"` - Comments string `json:"comments"` - commentQueue *CommentQueue + Directives []*NgxDirective `json:"directives"` + Locations []*NgxLocation `json:"locations"` + Comments string `json:"comments"` } type NgxUpstream struct { @@ -42,18 +37,6 @@ type NgxLocation struct { Comments string `json:"comments"` } -func (c *CommentQueue) DequeueAllComments() (comments string) { - for !c.Empty() { - comment, ok := c.Dequeue() - - if ok { - comments += strings.TrimSpace(comment.(string)) + "\n" - } - } - - return -} - func (d *NgxDirective) Orig() string { return d.Directive + " " + d.Params } @@ -65,16 +48,14 @@ func (d *NgxDirective) TrimParams() { func NewNgxServer() *NgxServer { return &NgxServer{ - Locations: make([]*NgxLocation, 0), - Directives: make([]*NgxDirective, 0), - commentQueue: &CommentQueue{linkedlistqueue.New()}, + Locations: make([]*NgxLocation, 0), + Directives: make([]*NgxDirective, 0), } } func NewNgxConfig(filename string) *NgxConfig { return &NgxConfig{ - FileName: filename, - commentQueue: &CommentQueue{linkedlistqueue.New()}, - Upstreams: make([]*NgxUpstream, 0), + FileName: filename, + Upstreams: make([]*NgxUpstream, 0), } } diff --git a/server/router/routers.go b/server/router/routers.go index f44fd8862..67c3f3c6a 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) @@ -68,27 +60,37 @@ func InitRouter() *gin.Engine { g.POST("ngx/build_config", api.BuildNginxConfig) // Tokenized nginx configuration to NgxConf g.POST("ngx/tokenize_config", api.TokenizeNginxConfig) + // Format nginx configuration code + g.POST("ngx/format_code", api.FormatNginxConfig) g.POST("domain/:name/enable", api.EnableDomain) g.POST("domain/:name/disable", api.DisableDomain) 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) g.GET("template", api.GetTemplate) + g.GET("template/configs", api.GetTemplateConfList) + g.GET("template/blocks", api.GetTemplateBlockList) + g.GET("template/block/:name", api.GetTemplateBlock) - g.GET("cert/issue/:domain", api.IssueCert) + 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) @@ -96,6 +98,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/service/template.go b/server/service/template.go new file mode 100644 index 000000000..54f5c2b37 --- /dev/null +++ b/server/service/template.go @@ -0,0 +1,149 @@ +package service + +import ( + "bufio" + "github.com/0xJacky/Nginx-UI/server/pkg/nginx" + "github.com/0xJacky/Nginx-UI/template" + "github.com/pkg/errors" + "github.com/tufanbarisyildirim/gonginx/parser" + "io" + "path/filepath" + "regexp" + "strings" +) + +type ConfigInfoItem struct { + Name string `json:"name"` + Description map[string]string `json:"description"` + Author string `json:"author"` + Filename string `json:"filename"` +} + +func GetTemplateInfo(path, name string) (configListItem ConfigInfoItem) { + configListItem = ConfigInfoItem{ + Description: make(map[string]string), + Filename: name, + } + + file, _ := template.DistFS.Open(filepath.Join(path, name)) + defer file.Close() + r := bufio.NewReader(file) + bytes, _, err := r.ReadLine() + if err == io.EOF { + return + } + line := strings.TrimSpace(string(bytes)) + + if line != "# Nginx UI Template Start" { + return + } + var content string + for { + bytes, _, err = r.ReadLine() + if err == io.EOF { + break + } + line = strings.TrimSpace(string(bytes)) + if line == "# Nginx UI Template End" { + break + } + content += line + "\n" + } + re := regexp.MustCompile(`# (\S+): (.*)`) + matches := re.FindAllStringSubmatch(content, -1) + for _, match := range matches { + if len(match) < 3 { + continue + } + key := match[1] + switch { + case key == "Name": + configListItem.Name = match[2] + case key == "Author": + configListItem.Author = match[2] + case strings.Contains(key, "Description"): + re = regexp.MustCompile(`(\w+)\[(\w+)\]`) + matches = re.FindAllStringSubmatch(key, -1) + for _, m := range matches { + if len(m) < 3 { + continue + } + // lang => description + configListItem.Description[m[2]] = match[2] + } + } + } + + return +} + +type ConfigDetail struct { + Custom string `json:"custom"` + nginx.NgxServer +} + +func ParseTemplate(path, name string) (c ConfigDetail, err error) { + file, err := template.DistFS.Open(filepath.Join(path, name)) + if err != nil { + err = errors.Wrap(err, "error tokenized template") + return + } + defer file.Close() + + r := bufio.NewReader(file) + var flag bool + custom := "" + content := "" + for { + bytes, _, err := r.ReadLine() + if err == io.EOF { + break + } + orig := string(bytes) + line := strings.TrimSpace(orig) + switch { + case line == "# Nginx UI Custom Start": + flag = true + case line == "# Nginx UI Custom End": + flag = false + case flag == true: + custom += orig + "\n" + case flag == false: + content += orig + "\n" + } + } + p := parser.NewStringParser(content) + config := p.Parse() + c.Custom = custom + for _, d := range config.GetDirectives() { + switch d.GetName() { + case nginx.Location: + l := &nginx.NgxLocation{ + Path: strings.Join(d.GetParameters(), " "), + } + l.ParseLocation(d, 0) + c.NgxServer.Locations = append(c.NgxServer.Locations, l) + default: + dir := &nginx.NgxDirective{ + Directive: d.GetName(), + } + dir.ParseDirective(d, 0) + c.NgxServer.Directives = append(c.NgxServer.Directives, dir) + } + } + return +} + +func GetTemplateList(path string) (configList []ConfigInfoItem, err error) { + configs, err := template.DistFS.ReadDir(path) + if err != nil { + err = errors.Wrap(err, "error get template list") + return + } + + for _, config := range configs { + configList = append(configList, GetTemplateInfo(path, config.Name())) + } + + return +} diff --git a/server/settings/settings.go b/server/settings/settings.go index cc182b02c..2b4c53596 100644 --- a/server/settings/settings.go +++ b/server/settings/settings.go @@ -16,21 +16,21 @@ var ( ) type Server struct { - HttpPort string - RunMode string - WebSocketToken string - JwtSecret string - HTTPChallengePort string - Email string - Database string - StartCmd 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{ @@ -41,6 +41,7 @@ var ServerSettings = &Server{ StartCmd: "login", Demo: false, PageSize: 10, + CADir: "", } var NginxLogSettings = &NginxLog{ diff --git a/server/test/ngx_conf_parse_test.go b/server/test/ngx_conf_parse_test.go deleted file mode 100644 index e61b497fe..000000000 --- a/server/test/ngx_conf_parse_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package test - -import ( - "fmt" - "github.com/0xJacky/Nginx-UI/server/pkg/nginx" - "testing" -) - -func TestNgxConfParse(t *testing.T) { - c, err := nginx.ParseNgxConfig("nextcloud_ngx.conf") - - if err != nil { - t.Fatal(err) - } - - fmt.Println(c.FileName) - // directive in root - fmt.Println("Upstream") - for _, u := range c.Upstreams { - fmt.Println("upstream name", u.Name) - fmt.Printf("comments\n%v", u.Comments) - for _, d := range u.Directives { - fmt.Println("u.Directives.d", d) - } - } - fmt.Println("==========================") - fmt.Println("Servers") - for _, s := range c.Servers { - fmt.Printf("comments\n%v", s.Comments) - for _, d := range s.Directives { - fmt.Println(d) - } - // locations - for _, location := range s.Locations { - fmt.Printf("comments\n%v", location.Comments) - fmt.Println("path", location.Path) - fmt.Println("content", location.Content) - fmt.Println("==========================") - } - } - -} diff --git a/template/block/codeigniter.conf b/template/block/codeigniter.conf new file mode 100644 index 000000000..49b01ccf5 --- /dev/null +++ b/template/block/codeigniter.conf @@ -0,0 +1,9 @@ +# Nginx UI Template Start +# Name: Codeigniter Rewrite +# Description[en]: Codeigniter URL Rewrite Config +# Description[zh_CN]: Codeigniter 伪静态配置 +# Author: @0xJacky +# Nginx UI Template End +location / { + try_files $uri $uri/ /index.php; +} diff --git a/template/block/enable-php-8.conf b/template/block/enable-php-8.conf new file mode 100644 index 000000000..dd3fcd277 --- /dev/null +++ b/template/block/enable-php-8.conf @@ -0,0 +1,13 @@ +# Nginx UI Template Start +# Name: PHP8.1 +# Description[en]: Enabled PHP 8.1 Config +# Description[zh_CN]: 启用 PHP 8.1 配置 +# Author: @0xJacky +# Nginx UI Template End +location ~ [^/]\.php(/|$) +{ + try_files $uri =404; + fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; + fastcgi_index index.php; + include fastcgi.conf; +} diff --git a/template/block/laravel.conf b/template/block/laravel.conf new file mode 100644 index 000000000..5bcad2be3 --- /dev/null +++ b/template/block/laravel.conf @@ -0,0 +1,9 @@ +# Nginx UI Template Start +# Name: Laravel Rewrite +# Description[en]: Laravel URL Rewrite Config +# Description[zh_CN]: Laravel 伪静态配置 +# Author: @0xJacky +# Nginx UI Template End +location / { + try_files $uri $uri/ /server.php?$query_string; +} diff --git a/template/block/nginx-ui.conf b/template/block/nginx-ui.conf new file mode 100644 index 000000000..fafb004f4 --- /dev/null +++ b/template/block/nginx-ui.conf @@ -0,0 +1,23 @@ +# Nginx UI Template Start +# Name: Nginx UI +# Description[en]: Nginx UI Config Template +# Description[zh_CN]: Nginx UI 配置模板 +# Author: @0xJacky +# Nginx UI Template End + +# Nginx UI Custom Start +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} +# Nginx UI Custom End +location / { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_pass http://127.0.0.1:9000/; +} diff --git a/template/block/reverse_proxy.conf b/template/block/reverse_proxy.conf new file mode 100644 index 000000000..84913c93b --- /dev/null +++ b/template/block/reverse_proxy.conf @@ -0,0 +1,15 @@ +# Nginx UI Template Start +# Name: Reverse Proxy +# Description[en]: Reverse Proxy Config +# Description[zh_CN]: 反向代理配置 +# Author: @0xJacky +# Nginx UI Template End +location / { + proxy_pass http://127.0.0.1:9000/; + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + client_max_body_size 1000m; + } diff --git a/template/block/reverse_proxy_ws.conf b/template/block/reverse_proxy_ws.conf new file mode 100644 index 000000000..0b6934b58 --- /dev/null +++ b/template/block/reverse_proxy_ws.conf @@ -0,0 +1,26 @@ +# Nginx UI Template Start +# Name: Reverse Proxy WebSocket +# Description[en]: Reverse Proxy with WebSocket Config +# Description[zh_CN]: 反向代理 WebSocket 配置 +# Author: @0xJacky +# Nginx UI Template End + +# Nginx UI Custom Start +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} +# Nginx UI Custom End + +location / { + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_pass http://127.0.0.1:9000/; + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + client_max_body_size 1000m; + } diff --git a/template/block/wordpress.conf b/template/block/wordpress.conf new file mode 100644 index 000000000..7c89da624 --- /dev/null +++ b/template/block/wordpress.conf @@ -0,0 +1,12 @@ +# Nginx UI Template Start +# Name: WordPress +# Description[en]: WordPress Config Template +# Description[zh_CN]: WordPress 配置模板 +# Author: @0xJacky +# Nginx UI Template End +location / { + try_files $uri $uri/ /index.php?$args; +} + +# Add trailing slash to */wp-admin requests. +rewrite /wp-admin$ $scheme://$host$uri/ permanent; diff --git a/template/conf/wordpress.conf b/template/conf/wordpress.conf new file mode 100644 index 000000000..7c89da624 --- /dev/null +++ b/template/conf/wordpress.conf @@ -0,0 +1,12 @@ +# Nginx UI Template Start +# Name: WordPress +# Description[en]: WordPress Config Template +# Description[zh_CN]: WordPress 配置模板 +# Author: @0xJacky +# Nginx UI Template End +location / { + try_files $uri $uri/ /index.php?$args; +} + +# Add trailing slash to */wp-admin requests. +rewrite /wp-admin$ $scheme://$host$uri/ permanent; diff --git a/template/template.go b/template/template.go new file mode 100644 index 000000000..43959d82d --- /dev/null +++ b/template/template.go @@ -0,0 +1,6 @@ +package template + +import "embed" + +//go:embed conf/* block/* +var DistFS embed.FS