bug fix and translated login error msg

This commit is contained in:
0xJacky 2022-08-11 21:30:44 +08:00
parent f11fd19288
commit b2e837f4b1
No known key found for this signature in database
GPG key ID: B6E4A6E4A561BAF0
35 changed files with 324 additions and 301 deletions

View file

@ -11,3 +11,6 @@ export default createGettext({
translations: translations,
silent: true
})
export class useGettext {
}

View file

@ -0,0 +1,7 @@
import gettext from '@/gettext'
const {$gettext} = gettext
export const msg = [
$gettext('The username or password is incorrect')
]

View file

@ -25,7 +25,7 @@ msgstr ""
#: 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:33
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:34
msgid "Add Directive Below"
msgstr "Add Directive Below"
@ -60,7 +60,7 @@ msgstr "Auto-renewal disabled for %{name}"
msgid "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"
msgstr "Back"
@ -101,7 +101,7 @@ 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:7
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:145
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:154
msgid "Comments"
msgstr "Comments"
@ -304,7 +304,7 @@ msgstr "Login successful"
msgid "Logout successful"
msgstr "Logout successful"
#: 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."
@ -384,7 +384,7 @@ msgstr "Not Found"
msgid "Not Valid Before: %{date}"
msgstr "Not Valid Before: %{date}"
#: 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."
@ -402,7 +402,7 @@ msgstr ""
msgid "OS:"
msgstr "OS:"
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:21
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:22
msgid "Params"
msgstr "Params"
@ -447,13 +447,13 @@ msgstr "Receive"
msgid "Reset"
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"
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
msgid "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/domain/DomainEdit.vue:56 src/views/domain/DomainEdit.vue:65
#: 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"
msgstr "Server error"
@ -494,11 +494,11 @@ msgstr "Server Info"
msgid "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"
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
msgid "server_name parameters more than one"
msgstr "server_name parameters more than one"
@ -536,7 +536,7 @@ msgstr "Enabled"
msgid "Terminal"
msgstr "Terminal"
#: 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."
@ -548,6 +548,10 @@ msgstr ""
msgid "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/user/User.vue:36
msgid "Updated at"

View file

@ -19,7 +19,7 @@ msgstr ""
#: 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:33
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:34
msgid "Add Directive Below"
msgstr ""
@ -54,7 +54,7 @@ msgstr ""
msgid "Auto-renewal enabled for %{name}"
msgstr ""
#: src/views/domain/DomainEdit.vue:158
#: src/views/domain/DomainEdit.vue:166
msgid "Back"
msgstr ""
@ -94,7 +94,7 @@ 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:7
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:145
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:154
msgid "Comments"
msgstr ""
@ -308,7 +308,7 @@ msgstr ""
msgid "Logout successful"
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."
msgstr ""
@ -387,7 +387,7 @@ msgstr ""
msgid "Not Valid Before: %{date}"
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."
msgstr ""
@ -401,7 +401,7 @@ msgstr ""
msgid "OS:"
msgstr ""
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:21
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:22
msgid "Params"
msgstr ""
@ -451,13 +451,13 @@ msgid "Reset"
msgstr ""
#: src/views/config/ConfigEdit.vue:52
#: src/views/domain/DomainEdit.vue:161
#: src/views/domain/DomainEdit.vue:169
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
msgid "Save Directive"
msgstr ""
@ -492,7 +492,6 @@ msgstr ""
#: src/views/domain/DomainEdit.vue:83
#: src/views/domain/DomainList.vue:78
#: src/views/other/Install.vue:71
#: src/views/other/Login.vue:56
msgid "Server error"
msgstr ""
@ -504,12 +503,12 @@ msgstr ""
msgid "server_name not found in directives"
msgstr ""
#: src/views/domain/cert/IssueCert.vue:155
#: src/views/domain/cert/IssueCert.vue:164
#: src/views/domain/DomainAdd.vue:112
msgid "server_name parameter is required"
msgstr ""
#: src/views/domain/cert/IssueCert.vue:158
#: src/views/domain/cert/IssueCert.vue:167
#: src/views/domain/cert/IssueCert.vue:34
msgid "server_name parameters more than one"
msgstr ""
@ -547,7 +546,7 @@ msgstr ""
msgid "Terminal"
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."
msgstr ""
@ -555,6 +554,10 @@ msgstr ""
msgid "The filename cannot contain the following characters: %{c}"
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/user/User.vue:36

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -28,7 +28,7 @@ msgstr "添加"
#: 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:33
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:34
msgid "Add Directive Below"
msgstr "在下面添加指令"
@ -62,7 +62,7 @@ msgstr "成功关闭 %{name} 自动续签"
msgid "Auto-renewal enabled for %{name}"
msgstr "成功启用 %{name} 自动续签"
#: src/views/domain/DomainEdit.vue:158
#: src/views/domain/DomainEdit.vue:166
msgid "Back"
msgstr "返回"
@ -102,7 +102,7 @@ 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:7
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:145
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:154
msgid "Comments"
msgstr "注释"
@ -304,7 +304,7 @@ msgstr "登录成功"
msgid "Logout successful"
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."
@ -383,7 +383,7 @@ msgstr "找不到页面"
msgid "Not Valid Before: %{date}"
msgstr "此前无效: %{date}"
#: 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."
@ -399,7 +399,7 @@ msgstr "确定"
msgid "OS:"
msgstr ""
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:21
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:22
msgid "Params"
msgstr "参数"
@ -444,13 +444,13 @@ msgstr "下载"
msgid "Reset"
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"
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
msgid "Save Directive"
msgstr "保存指令"
@ -478,7 +478,7 @@ msgstr "上传"
#: 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: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"
msgstr "服务器错误"
@ -490,11 +490,11 @@ msgstr "服务器信息"
msgid "server_name not found in directives"
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"
msgstr "必须为 server_name 指令指明参数"
#: src/views/domain/cert/IssueCert.vue:158
#: src/views/domain/cert/IssueCert.vue:167
#: src/views/domain/cert/IssueCert.vue:34
msgid "server_name parameters more than one"
msgstr "server_name 指令包含多个参数"
@ -531,7 +531,7 @@ msgstr "列表"
msgid "Terminal"
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."
@ -542,6 +542,10 @@ msgstr ""
msgid "The filename cannot contain the following characters: %{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/user/User.vue:36
msgid "Updated at"

View file

@ -29,7 +29,7 @@ msgstr ""
#: 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:33
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:34
msgid "Add Directive Below"
msgstr "在下面新增指令"
@ -64,7 +64,7 @@ msgstr "已關閉 %{name} 自動續簽"
msgid "Auto-renewal enabled for %{name}"
msgstr "已啟用 %{name} 自動續簽"
#: src/views/domain/DomainEdit.vue:158
#: src/views/domain/DomainEdit.vue:166
msgid "Back"
msgstr "返回"
@ -105,7 +105,7 @@ 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:7
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:145
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:154
msgid "Comments"
msgstr "註釋"
@ -309,7 +309,7 @@ msgstr "登入成功"
msgid "Logout successful"
msgstr "登出成功"
#: src/views/domain/cert/IssueCert.vue:172
#: src/views/domain/cert/IssueCert.vue:181
#, fuzzy
msgid ""
"Make sure you have configured a reverse proxy for .well-known directory to "
@ -390,7 +390,7 @@ msgstr "找不到頁面"
msgid "Not Valid Before: %{date}"
msgstr "此前無效: %{date}"
#: src/views/domain/cert/IssueCert.vue:164
#: src/views/domain/cert/IssueCert.vue:173
#, fuzzy
msgid ""
"Note: The server_name in the current configuration must be the domain name "
@ -407,7 +407,7 @@ msgstr "確定"
msgid "OS:"
msgstr "作業系統:"
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:21
#: src/views/domain/ngx_conf/directive/DirectiveAdd.vue:22
msgid "Params"
msgstr "參數"
@ -452,13 +452,13 @@ msgstr "下載"
msgid "Reset"
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"
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
msgid "Save Directive"
msgstr "儲存指令"
@ -487,7 +487,7 @@ msgstr "上傳"
#: 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: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"
msgstr "伺服器錯誤"
@ -499,11 +499,11 @@ msgstr "伺服器資訊"
msgid "server_name not found in directives"
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"
msgstr "必須為 server_name 指令指明參數"
#: src/views/domain/cert/IssueCert.vue:158
#: src/views/domain/cert/IssueCert.vue:167
#: src/views/domain/cert/IssueCert.vue:34
msgid "server_name parameters more than one"
msgstr "server_name 指令包含多個參數"
@ -541,7 +541,7 @@ msgstr "啟用"
msgid "Terminal"
msgstr "終端"
#: src/views/domain/cert/IssueCert.vue:168
#: src/views/domain/cert/IssueCert.vue:177
#, fuzzy
msgid ""
"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}"
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/user/User.vue:36
msgid "Updated at"

View file

@ -53,7 +53,7 @@ const onSubmit = () => {
const next = (route.query?.next || '').toString() || '/'
await router.push(next)
}).catch(e => {
message.error(e.message ?? $gettext('Server error'))
message.error($gettext(e.message ?? 'Server error'))
})
})
}

View file

@ -5,10 +5,10 @@ import (
"flag"
"github.com/0xJacky/Nginx-UI/server/analytic"
"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/settings"
"github.com/0xJacky/Nginx-UI/server/tool"
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
"github.com/gin-gonic/gin"
"github.com/go-co-op/gocron"
"log"
@ -40,7 +40,7 @@ func main() {
model.Init()
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 {
log.Fatalf("AutoCert Job: %v, Err: %v\n", job, err)

View file

@ -41,8 +41,9 @@ func BindAndValid(c *gin.Context, target interface{}) bool {
if !ok {
log.Println("verrs", verrs)
c.JSON(http.StatusNotAcceptable, gin.H{
"message": "请求参数错误",
"message": "Requested with wrong parameters",
"code": http.StatusNotAcceptable,
"error": verrs,
})
return false
}
@ -56,7 +57,7 @@ func BindAndValid(c *gin.Context, target interface{}) bool {
c.JSON(http.StatusNotAcceptable, gin.H{
"errors": errs,
"message": "请求参数错误",
"message": "Requested with wrong parameters",
"code": http.StatusNotAcceptable,
})

View file

@ -23,7 +23,7 @@ func Login(c *gin.Context) {
if err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(user.Password)); err != nil {
c.JSON(http.StatusForbidden, gin.H{
"message": "用户名或密码错误",
"message": "The username or password is incorrect",
})
return
}

View file

@ -1,8 +1,8 @@
package api
import (
"github.com/0xJacky/Nginx-UI/server/tool"
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
"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"
@ -13,7 +13,7 @@ import (
func CertInfo(c *gin.Context) {
domain := c.Param("domain")
key, err := tool.GetCertInfo(domain)
key, err := cert.GetCertInfo(domain)
if err != nil {
c.JSON(http.StatusOK, gin.H{
@ -61,7 +61,7 @@ func IssueCert(c *gin.Context) {
if mt == websocket.TextMessage && string(message) == "go" {
err = tool.IssueCert(domain)
err = cert.IssueCert(domain)
if err != nil {

View file

@ -1,10 +1,9 @@
package api
import (
"github.com/0xJacky/Nginx-UI/server/tool"
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
"github.com/0xJacky/Nginx-UI/server/pkg/config_list"
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
"github.com/gin-gonic/gin"
"io/ioutil"
"log"
"net/http"
"os"
@ -21,7 +20,7 @@ func GetConfigs(c *gin.Context) {
"modify": "time",
}
configFiles, err := ioutil.ReadDir(nginx.GetNginxConfPath("/"))
configFiles, err := os.ReadDir(nginx.GetNginxConfPath("/"))
if err != nil {
ErrHandler(c, err)
@ -32,17 +31,18 @@ func GetConfigs(c *gin.Context) {
for i := range configFiles {
file := configFiles[i]
fileInfo, _ := file.Info()
if !file.IsDir() && "." != file.Name()[0:1] {
configs = append(configs, gin.H{
"name": file.Name(),
"size": file.Size(),
"modify": file.ModTime(),
"size": fileInfo.Size(),
"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{
"data": configs,
@ -53,7 +53,7 @@ func GetConfig(c *gin.Context) {
name := c.Param("name")
path := filepath.Join(nginx.GetNginxConfPath("/"), name)
content, err := ioutil.ReadFile(path)
content, err := os.ReadFile(path)
if err != nil {
ErrHandler(c, err)
@ -93,7 +93,7 @@ func AddConfig(c *gin.Context) {
}
if content != "" {
err := ioutil.WriteFile(path, []byte(content), 0644)
err = os.WriteFile(path, []byte(content), 0644)
if err != nil {
ErrHandler(c, err)
return
@ -131,7 +131,7 @@ func EditConfig(c *gin.Context) {
path := filepath.Join(nginx.GetNginxConfPath("/"), name)
content := request.Content
origContent, err := ioutil.ReadFile(path)
origContent, err := os.ReadFile(path)
if err != nil {
ErrHandler(c, err)
return
@ -139,7 +139,7 @@ func EditConfig(c *gin.Context) {
if content != "" && content != string(origContent) {
// model.CreateBackup(path)
err := ioutil.WriteFile(path, []byte(content), 0644)
err = os.WriteFile(path, []byte(content), 0644)
if err != nil {
ErrHandler(c, err)
return

View file

@ -2,10 +2,9 @@ package api
import (
"github.com/0xJacky/Nginx-UI/server/model"
"github.com/0xJacky/Nginx-UI/server/tool"
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
"github.com/0xJacky/Nginx-UI/server/pkg/config_list"
nginx2 "github.com/0xJacky/Nginx-UI/server/pkg/nginx"
"github.com/gin-gonic/gin"
"io/ioutil"
"net/http"
"os"
"path/filepath"
@ -22,14 +21,14 @@ func GetDomains(c *gin.Context) {
"modify": "time",
}
configFiles, err := ioutil.ReadDir(nginx.GetNginxConfPath("sites-available"))
configFiles, err := os.ReadDir(nginx2.GetNginxConfPath("sites-available"))
if err != nil {
ErrHandler(c, err)
return
}
enabledConfig, err := ioutil.ReadDir(filepath.Join(nginx.GetNginxConfPath("sites-enabled")))
enabledConfig, err := os.ReadDir(filepath.Join(nginx2.GetNginxConfPath("sites-enabled")))
if err != nil {
ErrHandler(c, err)
@ -45,17 +44,18 @@ func GetDomains(c *gin.Context) {
for i := range configFiles {
file := configFiles[i]
fileInfo, _ := file.Info()
if !file.IsDir() {
configs = append(configs, gin.H{
"name": file.Name(),
"size": file.Size(),
"modify": file.ModTime(),
"size": fileInfo.Size(),
"modify": fileInfo.ModTime(),
"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{
"data": configs,
@ -64,14 +64,14 @@ func GetDomains(c *gin.Context) {
func GetDomain(c *gin.Context) {
name := c.Param("name")
path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name)
path := filepath.Join(nginx2.GetNginxConfPath("sites-available"), name)
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
}
config, err := nginx.ParseNgxConfig(path)
config, err := nginx2.ParseNgxConfig(path)
if err != nil {
ErrHandler(c, err)
@ -95,18 +95,18 @@ func EditDomain(c *gin.Context) {
name := c.Param("name")
request := make(gin.H)
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 {
ErrHandler(c, err)
return
}
enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name)
enabledConfigFilePath := filepath.Join(nginx2.GetNginxConfPath("sites-enabled"), name)
if _, err = os.Stat(enabledConfigFilePath); err == nil {
// Test nginx configuration
err = nginx.TestNginxConf()
err = nginx2.TestNginxConf()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"message": err.Error(),
@ -114,7 +114,7 @@ func EditDomain(c *gin.Context) {
return
}
output := nginx.ReloadNginx()
output := nginx2.ReloadNginx()
if output != "" && strings.Contains(output, "error") {
c.JSON(http.StatusInternalServerError, gin.H{
@ -128,8 +128,8 @@ func EditDomain(c *gin.Context) {
}
func EnableDomain(c *gin.Context) {
configFilePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), c.Param("name"))
enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name"))
configFilePath := filepath.Join(nginx2.GetNginxConfPath("sites-available"), c.Param("name"))
enabledConfigFilePath := filepath.Join(nginx2.GetNginxConfPath("sites-enabled"), c.Param("name"))
_, err := os.Stat(configFilePath)
@ -148,7 +148,7 @@ func EnableDomain(c *gin.Context) {
}
// Test nginx config, if not pass then rollback.
err = nginx.TestNginxConf()
err = nginx2.TestNginxConf()
if err != nil {
_ = os.Remove(enabledConfigFilePath)
c.JSON(http.StatusInternalServerError, gin.H{
@ -157,7 +157,7 @@ func EnableDomain(c *gin.Context) {
return
}
output := nginx.ReloadNginx()
output := nginx2.ReloadNginx()
if output != "" && strings.Contains(output, "error") {
c.JSON(http.StatusInternalServerError, gin.H{
@ -172,7 +172,7 @@ func EnableDomain(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)
@ -196,7 +196,7 @@ func DisableDomain(c *gin.Context) {
return
}
output := nginx.ReloadNginx()
output := nginx2.ReloadNginx()
if output != "" {
c.JSON(http.StatusInternalServerError, gin.H{
@ -213,8 +213,8 @@ func DisableDomain(c *gin.Context) {
func DeleteDomain(c *gin.Context) {
var err error
name := c.Param("name")
availablePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), name)
enabledPath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name)
availablePath := filepath.Join(nginx2.GetNginxConfPath("sites-available"), name)
enabledPath := filepath.Join(nginx2.GetNginxConfPath("sites-enabled"), name)
if _, err = os.Stat(availablePath); os.IsNotExist(err) {
c.JSON(http.StatusNotFound, gin.H{

View file

@ -2,14 +2,14 @@ package api
import (
"bufio"
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
nginx2 "github.com/0xJacky/Nginx-UI/server/pkg/nginx"
"github.com/gin-gonic/gin"
"net/http"
"strings"
)
func BuildNginxConfig(c *gin.Context) {
var ngxConf nginx.NgxConfig
var ngxConf nginx2.NgxConfig
if !BindAndValid(c, &ngxConf) {
return
}
@ -30,7 +30,7 @@ func TokenizeNginxConfig(c *gin.Context) {
scanner := bufio.NewScanner(strings.NewReader(json.Content))
ngxConfig, err := nginx.ParseNgxConfigByScanner("", scanner)
ngxConfig, err := nginx2.ParseNgxConfigByScanner("", scanner)
if err != nil {
ErrHandler(c, err)

View file

@ -1,7 +1,7 @@
package api
import (
"github.com/0xJacky/Nginx-UI/server/tool/pty"
"github.com/0xJacky/Nginx-UI/server/pkg/pty"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"log"

View file

@ -1,8 +1,8 @@
package api
import (
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
"github.com/0xJacky/Nginx-UI/server/settings"
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
"github.com/gin-gonic/gin"
"net/http"
"strings"

View file

@ -91,7 +91,7 @@ func EditUser(c *gin.Context) {
}
edit.Name = json.Name
// 改密码加密
// encrypt passowrd
if json.Password != "" {
var pwd []byte
pwd, err = bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost)

View file

@ -1,8 +1,8 @@
package model
import (
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
"io/ioutil"
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
"os"
"path/filepath"
)
@ -29,7 +29,7 @@ func GetAutoCertList() (c []Cert) {
db.Find(&t)
// 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 {
return

View file

@ -1,8 +1,8 @@
package model
import (
"io/ioutil"
"log"
"os"
"path/filepath"
)
@ -36,7 +36,7 @@ func GetBackup(id int) (config ConfigBackup) {
}
func CreateBackup(path string) {
content, err := ioutil.ReadFile(path)
content, err := os.ReadFile(path)
if err != nil {
log.Println(err)
}

188
server/pkg/cert/cert.go Normal file
View 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
}

View file

@ -1,4 +1,4 @@
package tool
package config_list
import (
"github.com/gin-gonic/gin"

View file

@ -2,7 +2,7 @@ package test
import (
"fmt"
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
"io/ioutil"
"log"
"os"

View file

@ -2,7 +2,7 @@ package test
import (
"fmt"
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
"log"
"os"
"os/exec"
@ -35,6 +35,4 @@ func TestCert(t *testing.T) {
}
log.Println("[found]", "cert key")
log.Println("申请成功")
}

View file

@ -2,7 +2,7 @@ package test
import (
"fmt"
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
"testing"
)

View file

@ -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
}