mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 02:15:48 +02:00
bug fix and translated login error msg
This commit is contained in:
parent
f11fd19288
commit
b2e837f4b1
35 changed files with 324 additions and 301 deletions
|
@ -11,3 +11,6 @@ export default createGettext({
|
||||||
translations: translations,
|
translations: translations,
|
||||||
silent: true
|
silent: true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export class useGettext {
|
||||||
|
}
|
||||||
|
|
7
frontend/src/language/constants.ts
Normal file
7
frontend/src/language/constants.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import gettext from '@/gettext'
|
||||||
|
|
||||||
|
const {$gettext} = gettext
|
||||||
|
|
||||||
|
export const msg = [
|
||||||
|
$gettext('The username or password is incorrect')
|
||||||
|
]
|
|
@ -25,7 +25,7 @@ msgstr ""
|
||||||
|
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:31
|
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:31
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32
|
#: 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
|
||||||
msgid "Add Directive Below"
|
msgid "Add Directive Below"
|
||||||
msgstr "Add Directive Below"
|
msgstr "Add Directive Below"
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ msgstr "Auto-renewal disabled for %{name}"
|
||||||
msgid "Auto-renewal enabled for %{name}"
|
msgid "Auto-renewal enabled for %{name}"
|
||||||
msgstr "Auto-renewal enabled for %{name}"
|
msgstr "Auto-renewal enabled for %{name}"
|
||||||
|
|
||||||
#: src/views/domain/DomainEdit.vue:158
|
#: src/views/domain/DomainEdit.vue:166
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "Back"
|
msgstr "Back"
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ msgstr "Certificate Status"
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29
|
#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29
|
||||||
#: src/views/domain/ngx_conf/LocationEditor.vue:21
|
#: src/views/domain/ngx_conf/LocationEditor.vue:21
|
||||||
#: src/views/domain/ngx_conf/LocationEditor.vue:7
|
#: src/views/domain/ngx_conf/LocationEditor.vue:7
|
||||||
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:145
|
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:154
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Comments"
|
msgstr "Comments"
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ msgstr "Login successful"
|
||||||
msgid "Logout successful"
|
msgid "Logout successful"
|
||||||
msgstr "Logout successful"
|
msgstr "Logout successful"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:172
|
#: src/views/domain/cert/IssueCert.vue:181
|
||||||
msgid ""
|
msgid ""
|
||||||
"Make sure you have configured a reverse proxy for .well-known directory to "
|
"Make sure you have configured a reverse proxy for .well-known directory to "
|
||||||
"HTTPChallengePort (default: 9180) before getting the certificate."
|
"HTTPChallengePort (default: 9180) before getting the certificate."
|
||||||
|
@ -384,7 +384,7 @@ msgstr "Not Found"
|
||||||
msgid "Not Valid Before: %{date}"
|
msgid "Not Valid Before: %{date}"
|
||||||
msgstr "Not Valid Before: %{date}"
|
msgstr "Not Valid Before: %{date}"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:164
|
#: src/views/domain/cert/IssueCert.vue:173
|
||||||
msgid ""
|
msgid ""
|
||||||
"Note: The server_name in the current configuration must be the domain name "
|
"Note: The server_name in the current configuration must be the domain name "
|
||||||
"you need to get the certificate."
|
"you need to get the certificate."
|
||||||
|
@ -402,7 +402,7 @@ msgstr ""
|
||||||
msgid "OS:"
|
msgid "OS:"
|
||||||
msgstr "OS:"
|
msgstr "OS:"
|
||||||
|
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:21
|
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:22
|
||||||
msgid "Params"
|
msgid "Params"
|
||||||
msgstr "Params"
|
msgstr "Params"
|
||||||
|
|
||||||
|
@ -447,13 +447,13 @@ msgstr "Receive"
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:161
|
#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:169
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "Save"
|
msgstr "Save"
|
||||||
|
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32
|
#: 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:33
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:34
|
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:35
|
||||||
msgid "Save Directive"
|
msgid "Save Directive"
|
||||||
msgstr "Save Directive"
|
msgstr "Save Directive"
|
||||||
|
|
||||||
|
@ -482,7 +482,7 @@ msgstr "Send"
|
||||||
#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:44
|
#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:44
|
||||||
#: src/views/domain/DomainEdit.vue:56 src/views/domain/DomainEdit.vue:65
|
#: src/views/domain/DomainEdit.vue:56 src/views/domain/DomainEdit.vue:65
|
||||||
#: src/views/domain/DomainEdit.vue:83 src/views/domain/DomainList.vue:78
|
#: src/views/domain/DomainEdit.vue:83 src/views/domain/DomainList.vue:78
|
||||||
#: src/views/other/Install.vue:71 src/views/other/Login.vue:56
|
#: src/views/other/Install.vue:71
|
||||||
msgid "Server error"
|
msgid "Server error"
|
||||||
msgstr "Server error"
|
msgstr "Server error"
|
||||||
|
|
||||||
|
@ -494,11 +494,11 @@ msgstr "Server Info"
|
||||||
msgid "server_name not found in directives"
|
msgid "server_name not found in directives"
|
||||||
msgstr "server_name not found in directives"
|
msgstr "server_name not found in directives"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:155 src/views/domain/DomainAdd.vue:112
|
#: src/views/domain/cert/IssueCert.vue:164 src/views/domain/DomainAdd.vue:112
|
||||||
msgid "server_name parameter is required"
|
msgid "server_name parameter is required"
|
||||||
msgstr "server_name parameter is required"
|
msgstr "server_name parameter is required"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:158
|
#: src/views/domain/cert/IssueCert.vue:167
|
||||||
#: src/views/domain/cert/IssueCert.vue:34
|
#: src/views/domain/cert/IssueCert.vue:34
|
||||||
msgid "server_name parameters more than one"
|
msgid "server_name parameters more than one"
|
||||||
msgstr "server_name parameters more than one"
|
msgstr "server_name parameters more than one"
|
||||||
|
@ -536,7 +536,7 @@ msgstr "Enabled"
|
||||||
msgid "Terminal"
|
msgid "Terminal"
|
||||||
msgstr "Terminal"
|
msgstr "Terminal"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:168
|
#: src/views/domain/cert/IssueCert.vue:177
|
||||||
msgid ""
|
msgid ""
|
||||||
"The certificate for the domain will be checked every hour, and will be "
|
"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."
|
"renewed if it has been more than 1 month since it was last issued."
|
||||||
|
@ -548,6 +548,10 @@ msgstr ""
|
||||||
msgid "The filename cannot contain the following characters: %{c}"
|
msgid "The filename cannot contain the following characters: %{c}"
|
||||||
msgstr "The filename cannot contain the following characters: %{c}"
|
msgstr "The filename cannot contain the following characters: %{c}"
|
||||||
|
|
||||||
|
#: 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/config/Config.vue:17 src/views/domain/DomainList.vue:36
|
||||||
#: src/views/user/User.vue:36
|
#: src/views/user/User.vue:36
|
||||||
msgid "Updated at"
|
msgid "Updated at"
|
||||||
|
|
|
@ -19,7 +19,7 @@ msgstr ""
|
||||||
|
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:31
|
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:31
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32
|
#: 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
|
||||||
msgid "Add Directive Below"
|
msgid "Add Directive Below"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ msgstr ""
|
||||||
msgid "Auto-renewal enabled for %{name}"
|
msgid "Auto-renewal enabled for %{name}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/domain/DomainEdit.vue:158
|
#: src/views/domain/DomainEdit.vue:166
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ msgstr ""
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29
|
#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29
|
||||||
#: src/views/domain/ngx_conf/LocationEditor.vue:21
|
#: src/views/domain/ngx_conf/LocationEditor.vue:21
|
||||||
#: src/views/domain/ngx_conf/LocationEditor.vue:7
|
#: src/views/domain/ngx_conf/LocationEditor.vue:7
|
||||||
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:145
|
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:154
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -308,7 +308,7 @@ msgstr ""
|
||||||
msgid "Logout successful"
|
msgid "Logout successful"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:172
|
#: src/views/domain/cert/IssueCert.vue:181
|
||||||
msgid "Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate."
|
msgid "Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -387,7 +387,7 @@ msgstr ""
|
||||||
msgid "Not Valid Before: %{date}"
|
msgid "Not Valid Before: %{date}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:164
|
#: src/views/domain/cert/IssueCert.vue:173
|
||||||
msgid "Note: The server_name in the current configuration must be the domain name you need to get the certificate."
|
msgid "Note: The server_name in the current configuration must be the domain name you need to get the certificate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -401,7 +401,7 @@ msgstr ""
|
||||||
msgid "OS:"
|
msgid "OS:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:21
|
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:22
|
||||||
msgid "Params"
|
msgid "Params"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -451,13 +451,13 @@ msgid "Reset"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/config/ConfigEdit.vue:52
|
#: src/views/config/ConfigEdit.vue:52
|
||||||
#: src/views/domain/DomainEdit.vue:161
|
#: src/views/domain/DomainEdit.vue:169
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32
|
#: 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:33
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:34
|
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:35
|
||||||
msgid "Save Directive"
|
msgid "Save Directive"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -492,7 +492,6 @@ msgstr ""
|
||||||
#: src/views/domain/DomainEdit.vue:83
|
#: src/views/domain/DomainEdit.vue:83
|
||||||
#: src/views/domain/DomainList.vue:78
|
#: src/views/domain/DomainList.vue:78
|
||||||
#: src/views/other/Install.vue:71
|
#: src/views/other/Install.vue:71
|
||||||
#: src/views/other/Login.vue:56
|
|
||||||
msgid "Server error"
|
msgid "Server error"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -504,12 +503,12 @@ msgstr ""
|
||||||
msgid "server_name not found in directives"
|
msgid "server_name not found in directives"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:155
|
#: src/views/domain/cert/IssueCert.vue:164
|
||||||
#: src/views/domain/DomainAdd.vue:112
|
#: src/views/domain/DomainAdd.vue:112
|
||||||
msgid "server_name parameter is required"
|
msgid "server_name parameter is required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:158
|
#: src/views/domain/cert/IssueCert.vue:167
|
||||||
#: src/views/domain/cert/IssueCert.vue:34
|
#: src/views/domain/cert/IssueCert.vue:34
|
||||||
msgid "server_name parameters more than one"
|
msgid "server_name parameters more than one"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -547,7 +546,7 @@ msgstr ""
|
||||||
msgid "Terminal"
|
msgid "Terminal"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:168
|
#: src/views/domain/cert/IssueCert.vue:177
|
||||||
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."
|
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 ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -555,6 +554,10 @@ msgstr ""
|
||||||
msgid "The filename cannot contain the following characters: %{c}"
|
msgid "The filename cannot contain the following characters: %{c}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/language/constants.ts:6
|
||||||
|
msgid "The username or password is incorrect"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/config/Config.vue:17
|
#: src/views/config/Config.vue:17
|
||||||
#: src/views/domain/DomainList.vue:36
|
#: src/views/domain/DomainList.vue:36
|
||||||
#: src/views/user/User.vue:36
|
#: src/views/user/User.vue:36
|
||||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -28,7 +28,7 @@ msgstr "添加"
|
||||||
|
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:31
|
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:31
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32
|
#: 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
|
||||||
msgid "Add Directive Below"
|
msgid "Add Directive Below"
|
||||||
msgstr "在下面添加指令"
|
msgstr "在下面添加指令"
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ msgstr "成功关闭 %{name} 自动续签"
|
||||||
msgid "Auto-renewal enabled for %{name}"
|
msgid "Auto-renewal enabled for %{name}"
|
||||||
msgstr "成功启用 %{name} 自动续签"
|
msgstr "成功启用 %{name} 自动续签"
|
||||||
|
|
||||||
#: src/views/domain/DomainEdit.vue:158
|
#: src/views/domain/DomainEdit.vue:166
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "返回"
|
msgstr "返回"
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ msgstr "证书状态"
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29
|
#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29
|
||||||
#: src/views/domain/ngx_conf/LocationEditor.vue:21
|
#: src/views/domain/ngx_conf/LocationEditor.vue:21
|
||||||
#: src/views/domain/ngx_conf/LocationEditor.vue:7
|
#: src/views/domain/ngx_conf/LocationEditor.vue:7
|
||||||
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:145
|
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:154
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "注释"
|
msgstr "注释"
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ msgstr "登录成功"
|
||||||
msgid "Logout successful"
|
msgid "Logout successful"
|
||||||
msgstr "登出成功"
|
msgstr "登出成功"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:172
|
#: src/views/domain/cert/IssueCert.vue:181
|
||||||
msgid ""
|
msgid ""
|
||||||
"Make sure you have configured a reverse proxy for .well-known directory to "
|
"Make sure you have configured a reverse proxy for .well-known directory to "
|
||||||
"HTTPChallengePort (default: 9180) before getting the certificate."
|
"HTTPChallengePort (default: 9180) before getting the certificate."
|
||||||
|
@ -383,7 +383,7 @@ msgstr "找不到页面"
|
||||||
msgid "Not Valid Before: %{date}"
|
msgid "Not Valid Before: %{date}"
|
||||||
msgstr "此前无效: %{date}"
|
msgstr "此前无效: %{date}"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:164
|
#: src/views/domain/cert/IssueCert.vue:173
|
||||||
msgid ""
|
msgid ""
|
||||||
"Note: The server_name in the current configuration must be the domain name "
|
"Note: The server_name in the current configuration must be the domain name "
|
||||||
"you need to get the certificate."
|
"you need to get the certificate."
|
||||||
|
@ -399,7 +399,7 @@ msgstr "确定"
|
||||||
msgid "OS:"
|
msgid "OS:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:21
|
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:22
|
||||||
msgid "Params"
|
msgid "Params"
|
||||||
msgstr "参数"
|
msgstr "参数"
|
||||||
|
|
||||||
|
@ -444,13 +444,13 @@ msgstr "下载"
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr "重置"
|
msgstr "重置"
|
||||||
|
|
||||||
#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:161
|
#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:169
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "保存"
|
msgstr "保存"
|
||||||
|
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32
|
#: 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:33
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:34
|
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:35
|
||||||
msgid "Save Directive"
|
msgid "Save Directive"
|
||||||
msgstr "保存指令"
|
msgstr "保存指令"
|
||||||
|
|
||||||
|
@ -478,7 +478,7 @@ msgstr "上传"
|
||||||
#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:44
|
#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:44
|
||||||
#: src/views/domain/DomainEdit.vue:56 src/views/domain/DomainEdit.vue:65
|
#: src/views/domain/DomainEdit.vue:56 src/views/domain/DomainEdit.vue:65
|
||||||
#: src/views/domain/DomainEdit.vue:83 src/views/domain/DomainList.vue:78
|
#: src/views/domain/DomainEdit.vue:83 src/views/domain/DomainList.vue:78
|
||||||
#: src/views/other/Install.vue:71 src/views/other/Login.vue:56
|
#: src/views/other/Install.vue:71
|
||||||
msgid "Server error"
|
msgid "Server error"
|
||||||
msgstr "服务器错误"
|
msgstr "服务器错误"
|
||||||
|
|
||||||
|
@ -490,11 +490,11 @@ msgstr "服务器信息"
|
||||||
msgid "server_name not found in directives"
|
msgid "server_name not found in directives"
|
||||||
msgstr "未在指令集合中找到 server_name"
|
msgstr "未在指令集合中找到 server_name"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:155 src/views/domain/DomainAdd.vue:112
|
#: src/views/domain/cert/IssueCert.vue:164 src/views/domain/DomainAdd.vue:112
|
||||||
msgid "server_name parameter is required"
|
msgid "server_name parameter is required"
|
||||||
msgstr "必须为 server_name 指令指明参数"
|
msgstr "必须为 server_name 指令指明参数"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:158
|
#: src/views/domain/cert/IssueCert.vue:167
|
||||||
#: src/views/domain/cert/IssueCert.vue:34
|
#: src/views/domain/cert/IssueCert.vue:34
|
||||||
msgid "server_name parameters more than one"
|
msgid "server_name parameters more than one"
|
||||||
msgstr "server_name 指令包含多个参数"
|
msgstr "server_name 指令包含多个参数"
|
||||||
|
@ -531,7 +531,7 @@ msgstr "列表"
|
||||||
msgid "Terminal"
|
msgid "Terminal"
|
||||||
msgstr "终端"
|
msgstr "终端"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:168
|
#: src/views/domain/cert/IssueCert.vue:177
|
||||||
msgid ""
|
msgid ""
|
||||||
"The certificate for the domain will be checked every hour, and will be "
|
"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."
|
"renewed if it has been more than 1 month since it was last issued."
|
||||||
|
@ -542,6 +542,10 @@ msgstr ""
|
||||||
msgid "The filename cannot contain the following characters: %{c}"
|
msgid "The filename cannot contain the following characters: %{c}"
|
||||||
msgstr "文件名不能包含以下字符: %{c}"
|
msgstr "文件名不能包含以下字符: %{c}"
|
||||||
|
|
||||||
|
#: 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/config/Config.vue:17 src/views/domain/DomainList.vue:36
|
||||||
#: src/views/user/User.vue:36
|
#: src/views/user/User.vue:36
|
||||||
msgid "Updated at"
|
msgid "Updated at"
|
||||||
|
|
|
@ -29,7 +29,7 @@ msgstr ""
|
||||||
|
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:31
|
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:31
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32
|
#: 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
|
||||||
msgid "Add Directive Below"
|
msgid "Add Directive Below"
|
||||||
msgstr "在下面新增指令"
|
msgstr "在下面新增指令"
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ msgstr "已關閉 %{name} 自動續簽"
|
||||||
msgid "Auto-renewal enabled for %{name}"
|
msgid "Auto-renewal enabled for %{name}"
|
||||||
msgstr "已啟用 %{name} 自動續簽"
|
msgstr "已啟用 %{name} 自動續簽"
|
||||||
|
|
||||||
#: src/views/domain/DomainEdit.vue:158
|
#: src/views/domain/DomainEdit.vue:166
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "返回"
|
msgstr "返回"
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ msgstr "憑證狀態"
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29
|
#: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29
|
||||||
#: src/views/domain/ngx_conf/LocationEditor.vue:21
|
#: src/views/domain/ngx_conf/LocationEditor.vue:21
|
||||||
#: src/views/domain/ngx_conf/LocationEditor.vue:7
|
#: src/views/domain/ngx_conf/LocationEditor.vue:7
|
||||||
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:145
|
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:154
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "註釋"
|
msgstr "註釋"
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ msgstr "登入成功"
|
||||||
msgid "Logout successful"
|
msgid "Logout successful"
|
||||||
msgstr "登出成功"
|
msgstr "登出成功"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:172
|
#: src/views/domain/cert/IssueCert.vue:181
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
"Make sure you have configured a reverse proxy for .well-known directory to "
|
"Make sure you have configured a reverse proxy for .well-known directory to "
|
||||||
|
@ -390,7 +390,7 @@ msgstr "找不到頁面"
|
||||||
msgid "Not Valid Before: %{date}"
|
msgid "Not Valid Before: %{date}"
|
||||||
msgstr "此前無效: %{date}"
|
msgstr "此前無效: %{date}"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:164
|
#: src/views/domain/cert/IssueCert.vue:173
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
"Note: The server_name in the current configuration must be the domain name "
|
"Note: The server_name in the current configuration must be the domain name "
|
||||||
|
@ -407,7 +407,7 @@ msgstr "確定"
|
||||||
msgid "OS:"
|
msgid "OS:"
|
||||||
msgstr "作業系統:"
|
msgstr "作業系統:"
|
||||||
|
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:21
|
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:22
|
||||||
msgid "Params"
|
msgid "Params"
|
||||||
msgstr "參數"
|
msgstr "參數"
|
||||||
|
|
||||||
|
@ -452,13 +452,13 @@ msgstr "下載"
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:161
|
#: src/views/config/ConfigEdit.vue:52 src/views/domain/DomainEdit.vue:169
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "儲存"
|
msgstr "儲存"
|
||||||
|
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:32
|
#: 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:33
|
||||||
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:34
|
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:35
|
||||||
msgid "Save Directive"
|
msgid "Save Directive"
|
||||||
msgstr "儲存指令"
|
msgstr "儲存指令"
|
||||||
|
|
||||||
|
@ -487,7 +487,7 @@ msgstr "上傳"
|
||||||
#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:44
|
#: src/views/config/ConfigEdit.vue:22 src/views/domain/DomainEdit.vue:44
|
||||||
#: src/views/domain/DomainEdit.vue:56 src/views/domain/DomainEdit.vue:65
|
#: src/views/domain/DomainEdit.vue:56 src/views/domain/DomainEdit.vue:65
|
||||||
#: src/views/domain/DomainEdit.vue:83 src/views/domain/DomainList.vue:78
|
#: src/views/domain/DomainEdit.vue:83 src/views/domain/DomainList.vue:78
|
||||||
#: src/views/other/Install.vue:71 src/views/other/Login.vue:56
|
#: src/views/other/Install.vue:71
|
||||||
msgid "Server error"
|
msgid "Server error"
|
||||||
msgstr "伺服器錯誤"
|
msgstr "伺服器錯誤"
|
||||||
|
|
||||||
|
@ -499,11 +499,11 @@ msgstr "伺服器資訊"
|
||||||
msgid "server_name not found in directives"
|
msgid "server_name not found in directives"
|
||||||
msgstr "未在指令集合中找到 server_name"
|
msgstr "未在指令集合中找到 server_name"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:155 src/views/domain/DomainAdd.vue:112
|
#: src/views/domain/cert/IssueCert.vue:164 src/views/domain/DomainAdd.vue:112
|
||||||
msgid "server_name parameter is required"
|
msgid "server_name parameter is required"
|
||||||
msgstr "必須為 server_name 指令指明參數"
|
msgstr "必須為 server_name 指令指明參數"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:158
|
#: src/views/domain/cert/IssueCert.vue:167
|
||||||
#: src/views/domain/cert/IssueCert.vue:34
|
#: src/views/domain/cert/IssueCert.vue:34
|
||||||
msgid "server_name parameters more than one"
|
msgid "server_name parameters more than one"
|
||||||
msgstr "server_name 指令包含多個參數"
|
msgstr "server_name 指令包含多個參數"
|
||||||
|
@ -541,7 +541,7 @@ msgstr "啟用"
|
||||||
msgid "Terminal"
|
msgid "Terminal"
|
||||||
msgstr "終端"
|
msgstr "終端"
|
||||||
|
|
||||||
#: src/views/domain/cert/IssueCert.vue:168
|
#: src/views/domain/cert/IssueCert.vue:177
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
"The certificate for the domain will be checked every hour, and will be "
|
"The certificate for the domain will be checked every hour, and will be "
|
||||||
|
@ -554,6 +554,10 @@ msgstr ""
|
||||||
msgid "The filename cannot contain the following characters: %{c}"
|
msgid "The filename cannot contain the following characters: %{c}"
|
||||||
msgstr "檔名不能包含以下字元: %{c}"
|
msgstr "檔名不能包含以下字元: %{c}"
|
||||||
|
|
||||||
|
#: 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/config/Config.vue:17 src/views/domain/DomainList.vue:36
|
||||||
#: src/views/user/User.vue:36
|
#: src/views/user/User.vue:36
|
||||||
msgid "Updated at"
|
msgid "Updated at"
|
||||||
|
|
|
@ -53,7 +53,7 @@ const onSubmit = () => {
|
||||||
const next = (route.query?.next || '').toString() || '/'
|
const next = (route.query?.next || '').toString() || '/'
|
||||||
await router.push(next)
|
await router.push(next)
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
message.error(e.message ?? $gettext('Server error'))
|
message.error($gettext(e.message ?? 'Server error'))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
6
main.go
6
main.go
|
@ -5,10 +5,10 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"github.com/0xJacky/Nginx-UI/server/analytic"
|
"github.com/0xJacky/Nginx-UI/server/analytic"
|
||||||
"github.com/0xJacky/Nginx-UI/server/model"
|
"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/0xJacky/Nginx-UI/server/router"
|
"github.com/0xJacky/Nginx-UI/server/router"
|
||||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool"
|
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/go-co-op/gocron"
|
"github.com/go-co-op/gocron"
|
||||||
"log"
|
"log"
|
||||||
|
@ -40,7 +40,7 @@ func main() {
|
||||||
model.Init()
|
model.Init()
|
||||||
|
|
||||||
s := gocron.NewScheduler(time.UTC)
|
s := gocron.NewScheduler(time.UTC)
|
||||||
job, err := s.Every(1).Hour().SingletonMode().Do(tool.AutoCert)
|
job, err := s.Every(1).Hour().SingletonMode().Do(cert.AutoCert)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("AutoCert Job: %v, Err: %v\n", job, err)
|
log.Fatalf("AutoCert Job: %v, Err: %v\n", job, err)
|
||||||
|
|
|
@ -41,8 +41,9 @@ func BindAndValid(c *gin.Context, target interface{}) bool {
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Println("verrs", verrs)
|
log.Println("verrs", verrs)
|
||||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||||
"message": "请求参数错误",
|
"message": "Requested with wrong parameters",
|
||||||
"code": http.StatusNotAcceptable,
|
"code": http.StatusNotAcceptable,
|
||||||
|
"error": verrs,
|
||||||
})
|
})
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -56,7 +57,7 @@ func BindAndValid(c *gin.Context, target interface{}) bool {
|
||||||
|
|
||||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||||
"errors": errs,
|
"errors": errs,
|
||||||
"message": "请求参数错误",
|
"message": "Requested with wrong parameters",
|
||||||
"code": http.StatusNotAcceptable,
|
"code": http.StatusNotAcceptable,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ func Login(c *gin.Context) {
|
||||||
|
|
||||||
if err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(user.Password)); err != nil {
|
if err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(user.Password)); err != nil {
|
||||||
c.JSON(http.StatusForbidden, gin.H{
|
c.JSON(http.StatusForbidden, gin.H{
|
||||||
"message": "用户名或密码错误",
|
"message": "The username or password is incorrect",
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool"
|
"github.com/0xJacky/Nginx-UI/server/pkg/cert"
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
|
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"log"
|
"log"
|
||||||
|
@ -13,7 +13,7 @@ import (
|
||||||
func CertInfo(c *gin.Context) {
|
func CertInfo(c *gin.Context) {
|
||||||
domain := c.Param("domain")
|
domain := c.Param("domain")
|
||||||
|
|
||||||
key, err := tool.GetCertInfo(domain)
|
key, err := cert.GetCertInfo(domain)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
@ -61,7 +61,7 @@ func IssueCert(c *gin.Context) {
|
||||||
|
|
||||||
if mt == websocket.TextMessage && string(message) == "go" {
|
if mt == websocket.TextMessage && string(message) == "go" {
|
||||||
|
|
||||||
err = tool.IssueCert(domain)
|
err = cert.IssueCert(domain)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool"
|
"github.com/0xJacky/Nginx-UI/server/pkg/config_list"
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
|
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -21,7 +20,7 @@ func GetConfigs(c *gin.Context) {
|
||||||
"modify": "time",
|
"modify": "time",
|
||||||
}
|
}
|
||||||
|
|
||||||
configFiles, err := ioutil.ReadDir(nginx.GetNginxConfPath("/"))
|
configFiles, err := os.ReadDir(nginx.GetNginxConfPath("/"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrHandler(c, err)
|
ErrHandler(c, err)
|
||||||
|
@ -32,17 +31,18 @@ func GetConfigs(c *gin.Context) {
|
||||||
|
|
||||||
for i := range configFiles {
|
for i := range configFiles {
|
||||||
file := configFiles[i]
|
file := configFiles[i]
|
||||||
|
fileInfo, _ := file.Info()
|
||||||
|
|
||||||
if !file.IsDir() && "." != file.Name()[0:1] {
|
if !file.IsDir() && "." != file.Name()[0:1] {
|
||||||
configs = append(configs, gin.H{
|
configs = append(configs, gin.H{
|
||||||
"name": file.Name(),
|
"name": file.Name(),
|
||||||
"size": file.Size(),
|
"size": fileInfo.Size(),
|
||||||
"modify": file.ModTime(),
|
"modify": fileInfo.ModTime(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configs = tool.Sort(orderBy, sort, mySort[orderBy], configs)
|
configs = config_list.Sort(orderBy, sort, mySort[orderBy], configs)
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"data": configs,
|
"data": configs,
|
||||||
|
@ -53,7 +53,7 @@ func GetConfig(c *gin.Context) {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
path := filepath.Join(nginx.GetNginxConfPath("/"), name)
|
path := filepath.Join(nginx.GetNginxConfPath("/"), name)
|
||||||
|
|
||||||
content, err := ioutil.ReadFile(path)
|
content, err := os.ReadFile(path)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrHandler(c, err)
|
ErrHandler(c, err)
|
||||||
|
@ -93,7 +93,7 @@ func AddConfig(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if content != "" {
|
if content != "" {
|
||||||
err := ioutil.WriteFile(path, []byte(content), 0644)
|
err = os.WriteFile(path, []byte(content), 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrHandler(c, err)
|
ErrHandler(c, err)
|
||||||
return
|
return
|
||||||
|
@ -131,7 +131,7 @@ func EditConfig(c *gin.Context) {
|
||||||
path := filepath.Join(nginx.GetNginxConfPath("/"), name)
|
path := filepath.Join(nginx.GetNginxConfPath("/"), name)
|
||||||
content := request.Content
|
content := request.Content
|
||||||
|
|
||||||
origContent, err := ioutil.ReadFile(path)
|
origContent, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrHandler(c, err)
|
ErrHandler(c, err)
|
||||||
return
|
return
|
||||||
|
@ -139,7 +139,7 @@ func EditConfig(c *gin.Context) {
|
||||||
|
|
||||||
if content != "" && content != string(origContent) {
|
if content != "" && content != string(origContent) {
|
||||||
// model.CreateBackup(path)
|
// model.CreateBackup(path)
|
||||||
err := ioutil.WriteFile(path, []byte(content), 0644)
|
err = os.WriteFile(path, []byte(content), 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrHandler(c, err)
|
ErrHandler(c, err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -2,10 +2,9 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/0xJacky/Nginx-UI/server/model"
|
"github.com/0xJacky/Nginx-UI/server/model"
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool"
|
"github.com/0xJacky/Nginx-UI/server/pkg/config_list"
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
|
nginx2 "github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -22,14 +21,14 @@ func GetDomains(c *gin.Context) {
|
||||||
"modify": "time",
|
"modify": "time",
|
||||||
}
|
}
|
||||||
|
|
||||||
configFiles, err := ioutil.ReadDir(nginx.GetNginxConfPath("sites-available"))
|
configFiles, err := os.ReadDir(nginx2.GetNginxConfPath("sites-available"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrHandler(c, err)
|
ErrHandler(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
enabledConfig, err := ioutil.ReadDir(filepath.Join(nginx.GetNginxConfPath("sites-enabled")))
|
enabledConfig, err := os.ReadDir(filepath.Join(nginx2.GetNginxConfPath("sites-enabled")))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrHandler(c, err)
|
ErrHandler(c, err)
|
||||||
|
@ -45,17 +44,18 @@ func GetDomains(c *gin.Context) {
|
||||||
|
|
||||||
for i := range configFiles {
|
for i := range configFiles {
|
||||||
file := configFiles[i]
|
file := configFiles[i]
|
||||||
|
fileInfo, _ := file.Info()
|
||||||
if !file.IsDir() {
|
if !file.IsDir() {
|
||||||
configs = append(configs, gin.H{
|
configs = append(configs, gin.H{
|
||||||
"name": file.Name(),
|
"name": file.Name(),
|
||||||
"size": file.Size(),
|
"size": fileInfo.Size(),
|
||||||
"modify": file.ModTime(),
|
"modify": fileInfo.ModTime(),
|
||||||
"enabled": enabledConfigMap[file.Name()],
|
"enabled": enabledConfigMap[file.Name()],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configs = tool.Sort(orderBy, sort, mySort[orderBy], configs)
|
configs = config_list.Sort(orderBy, sort, mySort[orderBy], configs)
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"data": configs,
|
"data": configs,
|
||||||
|
@ -64,14 +64,14 @@ func GetDomains(c *gin.Context) {
|
||||||
|
|
||||||
func GetDomain(c *gin.Context) {
|
func GetDomain(c *gin.Context) {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name)
|
path := filepath.Join(nginx2.GetNginxConfPath("sites-available"), name)
|
||||||
|
|
||||||
enabled := true
|
enabled := true
|
||||||
if _, err := os.Stat(filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name)); os.IsNotExist(err) {
|
if _, err := os.Stat(filepath.Join(nginx2.GetNginxConfPath("sites-enabled"), name)); os.IsNotExist(err) {
|
||||||
enabled = false
|
enabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := nginx.ParseNgxConfig(path)
|
config, err := nginx2.ParseNgxConfig(path)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrHandler(c, err)
|
ErrHandler(c, err)
|
||||||
|
@ -95,18 +95,18 @@ func EditDomain(c *gin.Context) {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
request := make(gin.H)
|
request := make(gin.H)
|
||||||
err = c.BindJSON(&request)
|
err = c.BindJSON(&request)
|
||||||
path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name)
|
path := filepath.Join(nginx2.GetNginxConfPath("sites-available"), name)
|
||||||
|
|
||||||
err = ioutil.WriteFile(path, []byte(request["content"].(string)), 0644)
|
err = os.WriteFile(path, []byte(request["content"].(string)), 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrHandler(c, err)
|
ErrHandler(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name)
|
enabledConfigFilePath := filepath.Join(nginx2.GetNginxConfPath("sites-enabled"), name)
|
||||||
if _, err = os.Stat(enabledConfigFilePath); err == nil {
|
if _, err = os.Stat(enabledConfigFilePath); err == nil {
|
||||||
// Test nginx configuration
|
// Test nginx configuration
|
||||||
err = nginx.TestNginxConf()
|
err = nginx2.TestNginxConf()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{
|
c.JSON(http.StatusInternalServerError, gin.H{
|
||||||
"message": err.Error(),
|
"message": err.Error(),
|
||||||
|
@ -114,7 +114,7 @@ func EditDomain(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
output := nginx.ReloadNginx()
|
output := nginx2.ReloadNginx()
|
||||||
|
|
||||||
if output != "" && strings.Contains(output, "error") {
|
if output != "" && strings.Contains(output, "error") {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{
|
c.JSON(http.StatusInternalServerError, gin.H{
|
||||||
|
@ -128,8 +128,8 @@ func EditDomain(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func EnableDomain(c *gin.Context) {
|
func EnableDomain(c *gin.Context) {
|
||||||
configFilePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), c.Param("name"))
|
configFilePath := filepath.Join(nginx2.GetNginxConfPath("sites-available"), c.Param("name"))
|
||||||
enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name"))
|
enabledConfigFilePath := filepath.Join(nginx2.GetNginxConfPath("sites-enabled"), c.Param("name"))
|
||||||
|
|
||||||
_, err := os.Stat(configFilePath)
|
_, err := os.Stat(configFilePath)
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ func EnableDomain(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test nginx config, if not pass then rollback.
|
// Test nginx config, if not pass then rollback.
|
||||||
err = nginx.TestNginxConf()
|
err = nginx2.TestNginxConf()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = os.Remove(enabledConfigFilePath)
|
_ = os.Remove(enabledConfigFilePath)
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{
|
c.JSON(http.StatusInternalServerError, gin.H{
|
||||||
|
@ -157,7 +157,7 @@ func EnableDomain(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
output := nginx.ReloadNginx()
|
output := nginx2.ReloadNginx()
|
||||||
|
|
||||||
if output != "" && strings.Contains(output, "error") {
|
if output != "" && strings.Contains(output, "error") {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{
|
c.JSON(http.StatusInternalServerError, gin.H{
|
||||||
|
@ -172,7 +172,7 @@ func EnableDomain(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func DisableDomain(c *gin.Context) {
|
func DisableDomain(c *gin.Context) {
|
||||||
enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name"))
|
enabledConfigFilePath := filepath.Join(nginx2.GetNginxConfPath("sites-enabled"), c.Param("name"))
|
||||||
|
|
||||||
_, err := os.Stat(enabledConfigFilePath)
|
_, err := os.Stat(enabledConfigFilePath)
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ func DisableDomain(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
output := nginx.ReloadNginx()
|
output := nginx2.ReloadNginx()
|
||||||
|
|
||||||
if output != "" {
|
if output != "" {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{
|
c.JSON(http.StatusInternalServerError, gin.H{
|
||||||
|
@ -213,8 +213,8 @@ func DisableDomain(c *gin.Context) {
|
||||||
func DeleteDomain(c *gin.Context) {
|
func DeleteDomain(c *gin.Context) {
|
||||||
var err error
|
var err error
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
availablePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), name)
|
availablePath := filepath.Join(nginx2.GetNginxConfPath("sites-available"), name)
|
||||||
enabledPath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name)
|
enabledPath := filepath.Join(nginx2.GetNginxConfPath("sites-enabled"), name)
|
||||||
|
|
||||||
if _, err = os.Stat(availablePath); os.IsNotExist(err) {
|
if _, err = os.Stat(availablePath); os.IsNotExist(err) {
|
||||||
c.JSON(http.StatusNotFound, gin.H{
|
c.JSON(http.StatusNotFound, gin.H{
|
||||||
|
|
|
@ -2,14 +2,14 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
|
nginx2 "github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BuildNginxConfig(c *gin.Context) {
|
func BuildNginxConfig(c *gin.Context) {
|
||||||
var ngxConf nginx.NgxConfig
|
var ngxConf nginx2.NgxConfig
|
||||||
if !BindAndValid(c, &ngxConf) {
|
if !BindAndValid(c, &ngxConf) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ func TokenizeNginxConfig(c *gin.Context) {
|
||||||
|
|
||||||
scanner := bufio.NewScanner(strings.NewReader(json.Content))
|
scanner := bufio.NewScanner(strings.NewReader(json.Content))
|
||||||
|
|
||||||
ngxConfig, err := nginx.ParseNgxConfigByScanner("", scanner)
|
ngxConfig, err := nginx2.ParseNgxConfigByScanner("", scanner)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrHandler(c, err)
|
ErrHandler(c, err)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool/pty"
|
"github.com/0xJacky/Nginx-UI/server/pkg/pty"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"log"
|
"log"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
|
@ -91,7 +91,7 @@ func EditUser(c *gin.Context) {
|
||||||
}
|
}
|
||||||
edit.Name = json.Name
|
edit.Name = json.Name
|
||||||
|
|
||||||
// 改密码加密
|
// encrypt passowrd
|
||||||
if json.Password != "" {
|
if json.Password != "" {
|
||||||
var pwd []byte
|
var pwd []byte
|
||||||
pwd, err = bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost)
|
pwd, err = bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
|
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||||
"io/ioutil"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ func GetAutoCertList() (c []Cert) {
|
||||||
db.Find(&t)
|
db.Find(&t)
|
||||||
// check if this domain is enabled
|
// check if this domain is enabled
|
||||||
|
|
||||||
enabledConfig, err := ioutil.ReadDir(filepath.Join(nginx.GetNginxConfPath("sites-enabled")))
|
enabledConfig, err := os.ReadDir(filepath.Join(nginx.GetNginxConfPath("sites-enabled")))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ func GetBackup(id int) (config ConfigBackup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateBackup(path string) {
|
func CreateBackup(path string) {
|
||||||
content, err := ioutil.ReadFile(path)
|
content, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|
188
server/pkg/cert/cert.go
Normal file
188
server/pkg/cert/cert.go
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
package cert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"github.com/0xJacky/Nginx-UI/server/model"
|
||||||
|
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||||
|
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||||
|
"github.com/go-acme/lego/v4/certcrypto"
|
||||||
|
"github.com/go-acme/lego/v4/certificate"
|
||||||
|
"github.com/go-acme/lego/v4/challenge/http01"
|
||||||
|
"github.com/go-acme/lego/v4/lego"
|
||||||
|
"github.com/go-acme/lego/v4/registration"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MyUser You'll need a user or account type that implements acme.User
|
||||||
|
type MyUser struct {
|
||||||
|
Email string
|
||||||
|
Registration *registration.Resource
|
||||||
|
key crypto.PrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MyUser) GetEmail() string {
|
||||||
|
return u.Email
|
||||||
|
}
|
||||||
|
func (u *MyUser) GetRegistration() *registration.Resource {
|
||||||
|
return u.Registration
|
||||||
|
}
|
||||||
|
func (u *MyUser) GetPrivateKey() crypto.PrivateKey {
|
||||||
|
return u.key
|
||||||
|
}
|
||||||
|
|
||||||
|
func AutoCert() {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
log.Println("[AutoCert] Recover", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
log.Println("[AutoCert] Start")
|
||||||
|
autoCertList := model.GetAutoCertList()
|
||||||
|
for i := range autoCertList {
|
||||||
|
domain := autoCertList[i].Domain
|
||||||
|
key, err := GetCertInfo(domain)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("GetCertInfo Err", err)
|
||||||
|
// Get certificate info error, ignore this domain
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// before 1 mo
|
||||||
|
if time.Now().Before(key.NotBefore.AddDate(0, 1, 0)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// after 1 mo, reissue certificate
|
||||||
|
err = IssueCert(domain)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCertInfo(domain string) (key *x509.Certificate, err error) {
|
||||||
|
|
||||||
|
var response *http.Response
|
||||||
|
|
||||||
|
client := &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
DialContext: (&net.Dialer{
|
||||||
|
Timeout: 5 * time.Second,
|
||||||
|
}).DialContext,
|
||||||
|
DisableKeepAlives: true,
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
},
|
||||||
|
Timeout: 5 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.Get("https://" + domain)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "get cert info error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func(Body io.ReadCloser) {
|
||||||
|
err = Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}(response.Body)
|
||||||
|
|
||||||
|
key = response.TLS.PeerCertificates[0]
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func IssueCert(domain string) error {
|
||||||
|
// Create a user. New accounts need an email and private key to start.
|
||||||
|
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "issue cert generate key error")
|
||||||
|
}
|
||||||
|
|
||||||
|
myUser := MyUser{
|
||||||
|
Email: settings.ServerSettings.Email,
|
||||||
|
key: privateKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
config := lego.NewConfig(&myUser)
|
||||||
|
|
||||||
|
if settings.ServerSettings.Demo {
|
||||||
|
config.CADirURL = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Certificate.KeyType = certcrypto.RSA2048
|
||||||
|
|
||||||
|
// A client facilitates communication with the CA server.
|
||||||
|
client, err := lego.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "issue cert new client error")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.Challenge.SetHTTP01Provider(
|
||||||
|
http01.NewProviderServer("",
|
||||||
|
settings.ServerSettings.HTTPChallengePort,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "issue cert challenge fail")
|
||||||
|
}
|
||||||
|
|
||||||
|
// New users will need to register
|
||||||
|
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return errors.Wrap(err, "issue cert register fail")
|
||||||
|
}
|
||||||
|
myUser.Registration = reg
|
||||||
|
|
||||||
|
request := certificate.ObtainRequest{
|
||||||
|
Domains: []string{domain},
|
||||||
|
Bundle: true,
|
||||||
|
}
|
||||||
|
certificates, err := client.Certificate.Obtain(request)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "issue cert fail to obtain")
|
||||||
|
}
|
||||||
|
saveDir := nginx.GetNginxConfPath("ssl/" + domain)
|
||||||
|
if _, err = os.Stat(saveDir); os.IsNotExist(err) {
|
||||||
|
err = os.Mkdir(saveDir, 0755)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "issue cert fail to create")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each certificate comes back with the cert bytes, the bytes of the client's
|
||||||
|
// private key, and a certificate URL. SAVE THESE TO DISK.
|
||||||
|
err = os.WriteFile(filepath.Join(saveDir, "fullchain.cer"),
|
||||||
|
certificates.Certificate, 0644)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return errors.Wrap(err, "issue cert write fullchain.cer fail")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(filepath.Join(saveDir, domain+".key"),
|
||||||
|
certificates.PrivateKey, 0644)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return errors.Wrap(err, "issue cert write key fail")
|
||||||
|
}
|
||||||
|
|
||||||
|
nginx.ReloadNginx()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package tool
|
package config_list
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
|
@ -2,7 +2,7 @@ package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
|
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
|
@ -2,7 +2,7 @@ package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
|
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
@ -35,6 +35,4 @@ func TestCert(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("[found]", "cert key")
|
log.Println("[found]", "cert key")
|
||||||
|
|
||||||
log.Println("申请成功")
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
|
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,189 +0,0 @@
|
||||||
package tool
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto"
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"github.com/0xJacky/Nginx-UI/server/model"
|
|
||||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
|
||||||
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
|
|
||||||
"github.com/go-acme/lego/v4/certcrypto"
|
|
||||||
"github.com/go-acme/lego/v4/certificate"
|
|
||||||
"github.com/go-acme/lego/v4/challenge/http01"
|
|
||||||
"github.com/go-acme/lego/v4/lego"
|
|
||||||
"github.com/go-acme/lego/v4/registration"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MyUser You'll need a user or account type that implements acme.User
|
|
||||||
type MyUser struct {
|
|
||||||
Email string
|
|
||||||
Registration *registration.Resource
|
|
||||||
key crypto.PrivateKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *MyUser) GetEmail() string {
|
|
||||||
return u.Email
|
|
||||||
}
|
|
||||||
func (u *MyUser) GetRegistration() *registration.Resource {
|
|
||||||
return u.Registration
|
|
||||||
}
|
|
||||||
func (u *MyUser) GetPrivateKey() crypto.PrivateKey {
|
|
||||||
return u.key
|
|
||||||
}
|
|
||||||
|
|
||||||
func AutoCert() {
|
|
||||||
defer func() {
|
|
||||||
if err := recover(); err != nil {
|
|
||||||
log.Println("[AutoCert] Recover", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
log.Println("[AutoCert] Start")
|
|
||||||
autoCertList := model.GetAutoCertList()
|
|
||||||
for i := range autoCertList {
|
|
||||||
domain := autoCertList[i].Domain
|
|
||||||
key, err := GetCertInfo(domain)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("GetCertInfo Err", err)
|
|
||||||
// 获取证书信息失败,本次跳过
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// 未到一个月
|
|
||||||
if time.Now().Before(key.NotBefore.AddDate(0, 1, 0)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// 过一个月了,重新申请证书
|
|
||||||
err = IssueCert(domain)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetCertInfo(domain string) (key *x509.Certificate, err error) {
|
|
||||||
|
|
||||||
var response *http.Response
|
|
||||||
|
|
||||||
client := &http.Client{
|
|
||||||
Transport: &http.Transport{
|
|
||||||
DialContext: (&net.Dialer{
|
|
||||||
Timeout: 5 * time.Second,
|
|
||||||
}).DialContext,
|
|
||||||
DisableKeepAlives: true,
|
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
||||||
},
|
|
||||||
Timeout: 5 * time.Second,
|
|
||||||
}
|
|
||||||
|
|
||||||
response, err = client.Get("https://" + domain)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
err = errors.Wrap(err, "get cert info error")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func(Body io.ReadCloser) {
|
|
||||||
err = Body.Close()
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}(response.Body)
|
|
||||||
|
|
||||||
key = response.TLS.PeerCertificates[0]
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func IssueCert(domain string) error {
|
|
||||||
// Create a user. New accounts need an email and private key to start.
|
|
||||||
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "issue cert generate key error")
|
|
||||||
}
|
|
||||||
|
|
||||||
myUser := MyUser{
|
|
||||||
Email: settings.ServerSettings.Email,
|
|
||||||
key: privateKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
config := lego.NewConfig(&myUser)
|
|
||||||
|
|
||||||
if settings.ServerSettings.Demo {
|
|
||||||
config.CADirURL = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
|
||||||
}
|
|
||||||
|
|
||||||
config.Certificate.KeyType = certcrypto.RSA2048
|
|
||||||
|
|
||||||
// A client facilitates communication with the CA server.
|
|
||||||
client, err := lego.NewClient(config)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "issue cert new client error")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = client.Challenge.SetHTTP01Provider(
|
|
||||||
http01.NewProviderServer("",
|
|
||||||
settings.ServerSettings.HTTPChallengePort,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "issue cert challenge fail")
|
|
||||||
}
|
|
||||||
|
|
||||||
// New users will need to register
|
|
||||||
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return errors.Wrap(err, "issue cert register fail")
|
|
||||||
}
|
|
||||||
myUser.Registration = reg
|
|
||||||
|
|
||||||
request := certificate.ObtainRequest{
|
|
||||||
Domains: []string{domain},
|
|
||||||
Bundle: true,
|
|
||||||
}
|
|
||||||
certificates, err := client.Certificate.Obtain(request)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "issue cert fail to obtain")
|
|
||||||
}
|
|
||||||
saveDir := nginx.GetNginxConfPath("ssl/" + domain)
|
|
||||||
if _, err = os.Stat(saveDir); os.IsNotExist(err) {
|
|
||||||
err = os.Mkdir(saveDir, 0755)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "issue cert fail to create")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Each certificate comes back with the cert bytes, the bytes of the client's
|
|
||||||
// private key, and a certificate URL. SAVE THESE TO DISK.
|
|
||||||
err = ioutil.WriteFile(filepath.Join(saveDir, "fullchain.cer"),
|
|
||||||
certificates.Certificate, 0644)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return errors.Wrap(err, "issue cert write fullchain.cer fail")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(filepath.Join(saveDir, domain+".key"),
|
|
||||||
certificates.PrivateKey, 0644)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return errors.Wrap(err, "issue cert write key fail")
|
|
||||||
}
|
|
||||||
|
|
||||||
nginx.ReloadNginx()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue