Browse Source

Merge pull request #402 from 0xJacky/feat/beta.24

Feat/beta.24
Jacky 1 year ago
parent
commit
0e3a824c11

+ 2 - 0
api/certificate/issue.go

@@ -95,6 +95,8 @@ func IssueCert(c *gin.Context) {
 	log := &cert.Logger{}
 	log := &cert.Logger{}
 	log.SetCertModel(&certModel)
 	log.SetCertModel(&certModel)
 
 
+	payload.CertID = certModel.ID
+
 	go cert.IssueCert(payload, logChan, errChan)
 	go cert.IssueCert(payload, logChan, errChan)
 
 
 	go handleIssueCertLogChan(ws, log, logChan)
 	go handleIssueCertLogChan(ws, log, logChan)

+ 1 - 1
app/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "nginx-ui-app-next",
   "name": "nginx-ui-app-next",
-  "version": "2.0.0-beta.23",
+  "version": "2.0.0-beta.24",
   "type": "module",
   "type": "module",
   "scripts": {
   "scripts": {
     "dev": "vite",
     "dev": "vite",

+ 15 - 11
app/src/language/en/app.po

@@ -74,7 +74,7 @@ msgstr "Add Location"
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "Advance Mode"
 msgstr "Advance Mode"
 
 
-#: src/views/preference/OpenAISettings.vue:39
+#: src/views/preference/OpenAISettings.vue:42
 msgid "API Base Url"
 msgid "API Base Url"
 msgstr ""
 msgstr ""
 
 
@@ -82,11 +82,11 @@ msgstr ""
 msgid "API Document"
 msgid "API Document"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:51
+#: src/views/preference/OpenAISettings.vue:54
 msgid "API Proxy"
 msgid "API Proxy"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:63
+#: src/views/preference/OpenAISettings.vue:66
 msgid "API Token"
 msgid "API Token"
 msgstr ""
 msgstr ""
 
 
@@ -920,7 +920,7 @@ msgstr ""
 msgid "Leave blank for no change"
 msgid "Leave blank for no change"
 msgstr "Leave blank for no change"
 msgstr "Leave blank for no change"
 
 
-#: src/views/preference/OpenAISettings.vue:47
+#: src/views/preference/OpenAISettings.vue:50
 msgid "Leave blank for the default: https://api.openai.com/"
 msgid "Leave blank for the default: https://api.openai.com/"
 msgstr ""
 msgstr ""
 
 
@@ -1047,7 +1047,7 @@ msgstr "Memory and Storage"
 msgid "Minutes"
 msgid "Minutes"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:27
+#: src/views/preference/OpenAISettings.vue:30
 #, fuzzy
 #, fuzzy
 msgid "Model"
 msgid "Model"
 msgstr "Advance Mode"
 msgstr "Advance Mode"
@@ -1712,8 +1712,10 @@ msgstr ""
 msgid "The input is not a SSL Certificate Key"
 msgid "The input is not a SSL Certificate Key"
 msgstr "Certificate Status"
 msgstr "Certificate Status"
 
 
-#: src/views/preference/OpenAISettings.vue:30
-msgid "The model name should only contain letters, numbers, dashes, and dots."
+#: src/views/preference/OpenAISettings.vue:33
+msgid ""
+"The model name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/certificate/CertificateEditor.vue:165
 #: src/views/certificate/CertificateEditor.vue:165
@@ -1726,7 +1728,9 @@ msgid "The path exists, but the file is not a private key"
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/BasicSettings.vue:120
 #: src/views/preference/BasicSettings.vue:120
-msgid "The server name should only contain letters, numbers, dashes, and dots."
+msgid ""
+"The server name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
@@ -1743,8 +1747,8 @@ msgstr ""
 msgid "The url is invalid"
 msgid "The url is invalid"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:42
-#: src/views/preference/OpenAISettings.vue:54
+#: src/views/preference/OpenAISettings.vue:45
+#: src/views/preference/OpenAISettings.vue:57
 msgid "The url is invalid."
 msgid "The url is invalid."
 msgstr ""
 msgstr ""
 
 
@@ -1786,7 +1790,7 @@ msgid ""
 "continue?"
 "continue?"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:66
+#: src/views/preference/OpenAISettings.vue:69
 msgid "Token is not valid"
 msgid "Token is not valid"
 msgstr ""
 msgstr ""
 
 

+ 15 - 11
app/src/language/es/app.po

@@ -76,7 +76,7 @@ msgstr "Adicional"
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "Modo avanzado"
 msgstr "Modo avanzado"
 
 
-#: src/views/preference/OpenAISettings.vue:39
+#: src/views/preference/OpenAISettings.vue:42
 msgid "API Base Url"
 msgid "API Base Url"
 msgstr "URL Base de la API"
 msgstr "URL Base de la API"
 
 
@@ -85,11 +85,11 @@ msgstr "URL Base de la API"
 msgid "API Document"
 msgid "API Document"
 msgstr "Token de la API"
 msgstr "Token de la API"
 
 
-#: src/views/preference/OpenAISettings.vue:51
+#: src/views/preference/OpenAISettings.vue:54
 msgid "API Proxy"
 msgid "API Proxy"
 msgstr "Proxy de la API"
 msgstr "Proxy de la API"
 
 
-#: src/views/preference/OpenAISettings.vue:63
+#: src/views/preference/OpenAISettings.vue:66
 msgid "API Token"
 msgid "API Token"
 msgstr "Token de la API"
 msgstr "Token de la API"
 
 
@@ -883,7 +883,7 @@ msgstr "Comprobado por última vez el"
 msgid "Leave blank for no change"
 msgid "Leave blank for no change"
 msgstr "Para no modificar dejar en blanco"
 msgstr "Para no modificar dejar en blanco"
 
 
-#: src/views/preference/OpenAISettings.vue:47
+#: src/views/preference/OpenAISettings.vue:50
 msgid "Leave blank for the default: https://api.openai.com/"
 msgid "Leave blank for the default: https://api.openai.com/"
 msgstr "Dejar en blanco para el valor predeterminado: https://api.openai.com/"
 msgstr "Dejar en blanco para el valor predeterminado: https://api.openai.com/"
 
 
@@ -1002,7 +1002,7 @@ msgstr "Memoria y almacenamiento"
 msgid "Minutes"
 msgid "Minutes"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:27
+#: src/views/preference/OpenAISettings.vue:30
 #, fuzzy
 #, fuzzy
 msgid "Model"
 msgid "Model"
 msgstr "Modo de ejecución"
 msgstr "Modo de ejecución"
@@ -1649,8 +1649,10 @@ msgstr "La entrada no es un Certificado SSL"
 msgid "The input is not a SSL Certificate Key"
 msgid "The input is not a SSL Certificate Key"
 msgstr "La entrada no es una clave de certificado SSL"
 msgstr "La entrada no es una clave de certificado SSL"
 
 
-#: src/views/preference/OpenAISettings.vue:30
-msgid "The model name should only contain letters, numbers, dashes, and dots."
+#: src/views/preference/OpenAISettings.vue:33
+msgid ""
+"The model name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/certificate/CertificateEditor.vue:165
 #: src/views/certificate/CertificateEditor.vue:165
@@ -1663,7 +1665,9 @@ msgid "The path exists, but the file is not a private key"
 msgstr "La ruta existe, pero el archivo no es una clave privada"
 msgstr "La ruta existe, pero el archivo no es una clave privada"
 
 
 #: src/views/preference/BasicSettings.vue:120
 #: src/views/preference/BasicSettings.vue:120
-msgid "The server name should only contain letters, numbers, dashes, and dots."
+msgid ""
+"The server name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
@@ -1680,8 +1684,8 @@ msgstr ""
 msgid "The url is invalid"
 msgid "The url is invalid"
 msgstr "La URL no es válida"
 msgstr "La URL no es válida"
 
 
-#: src/views/preference/OpenAISettings.vue:42
-#: src/views/preference/OpenAISettings.vue:54
+#: src/views/preference/OpenAISettings.vue:45
+#: src/views/preference/OpenAISettings.vue:57
 #, fuzzy
 #, fuzzy
 msgid "The url is invalid."
 msgid "The url is invalid."
 msgstr "La URL no es válida"
 msgstr "La URL no es válida"
@@ -1728,7 +1732,7 @@ msgstr ""
 "de la autoridad al backend, y debemos guardar este archivo y volver a cargar "
 "de la autoridad al backend, y debemos guardar este archivo y volver a cargar "
 "Nginx. ¿Estás seguro de que quieres continuar?"
 "Nginx. ¿Estás seguro de que quieres continuar?"
 
 
-#: src/views/preference/OpenAISettings.vue:66
+#: src/views/preference/OpenAISettings.vue:69
 msgid "Token is not valid"
 msgid "Token is not valid"
 msgstr "El token no es válido"
 msgstr "El token no es válido"
 
 

+ 15 - 11
app/src/language/fr_FR/app.po

@@ -76,7 +76,7 @@ msgstr "Supplémentaire"
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "Mode avancé"
 msgstr "Mode avancé"
 
 
-#: src/views/preference/OpenAISettings.vue:39
+#: src/views/preference/OpenAISettings.vue:42
 msgid "API Base Url"
 msgid "API Base Url"
 msgstr "URL de base de l'API"
 msgstr "URL de base de l'API"
 
 
@@ -85,11 +85,11 @@ msgstr "URL de base de l'API"
 msgid "API Document"
 msgid "API Document"
 msgstr "Jeton d'API"
 msgstr "Jeton d'API"
 
 
-#: src/views/preference/OpenAISettings.vue:51
+#: src/views/preference/OpenAISettings.vue:54
 msgid "API Proxy"
 msgid "API Proxy"
 msgstr "Proxy d'API"
 msgstr "Proxy d'API"
 
 
-#: src/views/preference/OpenAISettings.vue:63
+#: src/views/preference/OpenAISettings.vue:66
 msgid "API Token"
 msgid "API Token"
 msgstr "Jeton d'API"
 msgstr "Jeton d'API"
 
 
@@ -917,7 +917,7 @@ msgstr "Dernière vérification le"
 msgid "Leave blank for no change"
 msgid "Leave blank for no change"
 msgstr "Laisser vide pour aucun changement"
 msgstr "Laisser vide pour aucun changement"
 
 
-#: src/views/preference/OpenAISettings.vue:47
+#: src/views/preference/OpenAISettings.vue:50
 msgid "Leave blank for the default: https://api.openai.com/"
 msgid "Leave blank for the default: https://api.openai.com/"
 msgstr "Laissez vide pour la valeur par défaut : https://api.openai.com/"
 msgstr "Laissez vide pour la valeur par défaut : https://api.openai.com/"
 
 
@@ -1046,7 +1046,7 @@ msgstr "Mémoire et stockage"
 msgid "Minutes"
 msgid "Minutes"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:27
+#: src/views/preference/OpenAISettings.vue:30
 #, fuzzy
 #, fuzzy
 msgid "Model"
 msgid "Model"
 msgstr "Mode d'exécution"
 msgstr "Mode d'exécution"
@@ -1714,8 +1714,10 @@ msgstr ""
 msgid "The input is not a SSL Certificate Key"
 msgid "The input is not a SSL Certificate Key"
 msgstr "Chemin de la clé du certificat SSL"
 msgstr "Chemin de la clé du certificat SSL"
 
 
-#: src/views/preference/OpenAISettings.vue:30
-msgid "The model name should only contain letters, numbers, dashes, and dots."
+#: src/views/preference/OpenAISettings.vue:33
+msgid ""
+"The model name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/certificate/CertificateEditor.vue:165
 #: src/views/certificate/CertificateEditor.vue:165
@@ -1728,7 +1730,9 @@ msgid "The path exists, but the file is not a private key"
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/BasicSettings.vue:120
 #: src/views/preference/BasicSettings.vue:120
-msgid "The server name should only contain letters, numbers, dashes, and dots."
+msgid ""
+"The server name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
@@ -1746,8 +1750,8 @@ msgstr ""
 msgid "The url is invalid"
 msgid "The url is invalid"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:42
-#: src/views/preference/OpenAISettings.vue:54
+#: src/views/preference/OpenAISettings.vue:45
+#: src/views/preference/OpenAISettings.vue:57
 msgid "The url is invalid."
 msgid "The url is invalid."
 msgstr ""
 msgstr ""
 
 
@@ -1796,7 +1800,7 @@ msgstr ""
 "transmettre la demande de l'autorité au backend, et nous devons enregistrer "
 "transmettre la demande de l'autorité au backend, et nous devons enregistrer "
 "ce fichier et recharger le Nginx. Êtes-vous sûr de vouloir continuer?"
 "ce fichier et recharger le Nginx. Êtes-vous sûr de vouloir continuer?"
 
 
-#: src/views/preference/OpenAISettings.vue:66
+#: src/views/preference/OpenAISettings.vue:69
 msgid "Token is not valid"
 msgid "Token is not valid"
 msgstr ""
 msgstr ""
 
 

+ 15 - 11
app/src/language/ko_KR/app.po

@@ -75,7 +75,7 @@ msgstr "추가적인"
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "고급 모드"
 msgstr "고급 모드"
 
 
-#: src/views/preference/OpenAISettings.vue:39
+#: src/views/preference/OpenAISettings.vue:42
 msgid "API Base Url"
 msgid "API Base Url"
 msgstr "API 기본 URL"
 msgstr "API 기본 URL"
 
 
@@ -84,11 +84,11 @@ msgstr "API 기본 URL"
 msgid "API Document"
 msgid "API Document"
 msgstr "API 토큰"
 msgstr "API 토큰"
 
 
-#: src/views/preference/OpenAISettings.vue:51
+#: src/views/preference/OpenAISettings.vue:54
 msgid "API Proxy"
 msgid "API Proxy"
 msgstr "API 프록시"
 msgstr "API 프록시"
 
 
-#: src/views/preference/OpenAISettings.vue:63
+#: src/views/preference/OpenAISettings.vue:66
 msgid "API Token"
 msgid "API Token"
 msgstr "API 토큰"
 msgstr "API 토큰"
 
 
@@ -890,7 +890,7 @@ msgstr "마지막 확인 시간"
 msgid "Leave blank for no change"
 msgid "Leave blank for no change"
 msgstr "변경사항이 없으면 비워두세요"
 msgstr "변경사항이 없으면 비워두세요"
 
 
-#: src/views/preference/OpenAISettings.vue:47
+#: src/views/preference/OpenAISettings.vue:50
 msgid "Leave blank for the default: https://api.openai.com/"
 msgid "Leave blank for the default: https://api.openai.com/"
 msgstr "기본값을 사용하려면 비워 두세요: https://api.openai.com/"
 msgstr "기본값을 사용하려면 비워 두세요: https://api.openai.com/"
 
 
@@ -1022,7 +1022,7 @@ msgstr "메모리 및 저장소"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "분"
 msgstr "분"
 
 
-#: src/views/preference/OpenAISettings.vue:27
+#: src/views/preference/OpenAISettings.vue:30
 #, fuzzy
 #, fuzzy
 msgid "Model"
 msgid "Model"
 msgstr "실행 모드"
 msgstr "실행 모드"
@@ -1690,8 +1690,10 @@ msgstr "입력이 SSL 인증서가 아닙니다"
 msgid "The input is not a SSL Certificate Key"
 msgid "The input is not a SSL Certificate Key"
 msgstr "Certificate Status"
 msgstr "Certificate Status"
 
 
-#: src/views/preference/OpenAISettings.vue:30
-msgid "The model name should only contain letters, numbers, dashes, and dots."
+#: src/views/preference/OpenAISettings.vue:33
+msgid ""
+"The model name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/certificate/CertificateEditor.vue:165
 #: src/views/certificate/CertificateEditor.vue:165
@@ -1704,7 +1706,9 @@ msgid "The path exists, but the file is not a private key"
 msgstr "경로는 존재하지만 파일은 개인 키가 아닙니다"
 msgstr "경로는 존재하지만 파일은 개인 키가 아닙니다"
 
 
 #: src/views/preference/BasicSettings.vue:120
 #: src/views/preference/BasicSettings.vue:120
-msgid "The server name should only contain letters, numbers, dashes, and dots."
+msgid ""
+"The server name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
@@ -1722,8 +1726,8 @@ msgstr ""
 msgid "The url is invalid"
 msgid "The url is invalid"
 msgstr "유효한 URL이 아닙니다"
 msgstr "유효한 URL이 아닙니다"
 
 
-#: src/views/preference/OpenAISettings.vue:42
-#: src/views/preference/OpenAISettings.vue:54
+#: src/views/preference/OpenAISettings.vue:45
+#: src/views/preference/OpenAISettings.vue:57
 #, fuzzy
 #, fuzzy
 msgid "The url is invalid."
 msgid "The url is invalid."
 msgstr "유효한 URL이 아닙니다"
 msgstr "유효한 URL이 아닙니다"
@@ -1769,7 +1773,7 @@ msgstr ""
 "시할 수 있는 위치를 추가해야 하며,이 파일을 저장하고 Nginx를 다시로드해야 합"
 "시할 수 있는 위치를 추가해야 하며,이 파일을 저장하고 Nginx를 다시로드해야 합"
 "니다.계속하시겠습니까?"
 "니다.계속하시겠습니까?"
 
 
-#: src/views/preference/OpenAISettings.vue:66
+#: src/views/preference/OpenAISettings.vue:69
 msgid "Token is not valid"
 msgid "Token is not valid"
 msgstr "토큰이 유효하지 않습니다"
 msgstr "토큰이 유효하지 않습니다"
 
 

+ 11 - 11
app/src/language/messages.pot

@@ -70,7 +70,7 @@ msgstr ""
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:39
+#: src/views/preference/OpenAISettings.vue:42
 msgid "API Base Url"
 msgid "API Base Url"
 msgstr ""
 msgstr ""
 
 
@@ -78,11 +78,11 @@ msgstr ""
 msgid "API Document"
 msgid "API Document"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:51
+#: src/views/preference/OpenAISettings.vue:54
 msgid "API Proxy"
 msgid "API Proxy"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:63
+#: src/views/preference/OpenAISettings.vue:66
 msgid "API Token"
 msgid "API Token"
 msgstr ""
 msgstr ""
 
 
@@ -885,7 +885,7 @@ msgstr ""
 msgid "Leave blank for no change"
 msgid "Leave blank for no change"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:47
+#: src/views/preference/OpenAISettings.vue:50
 msgid "Leave blank for the default: https://api.openai.com/"
 msgid "Leave blank for the default: https://api.openai.com/"
 msgstr ""
 msgstr ""
 
 
@@ -998,7 +998,7 @@ msgstr ""
 msgid "Minutes"
 msgid "Minutes"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:27
+#: src/views/preference/OpenAISettings.vue:30
 msgid "Model"
 msgid "Model"
 msgstr ""
 msgstr ""
 
 
@@ -1637,8 +1637,8 @@ msgstr ""
 msgid "The input is not a SSL Certificate Key"
 msgid "The input is not a SSL Certificate Key"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:30
-msgid "The model name should only contain letters, numbers, dashes, and dots."
+#: src/views/preference/OpenAISettings.vue:33
+msgid "The model name should only contain letters, unicode, numbers, hyphens, dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/certificate/CertificateEditor.vue:165
 #: src/views/certificate/CertificateEditor.vue:165
@@ -1650,7 +1650,7 @@ msgid "The path exists, but the file is not a private key"
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/BasicSettings.vue:120
 #: src/views/preference/BasicSettings.vue:120
-msgid "The server name should only contain letters, numbers, dashes, and dots."
+msgid "The server name should only contain letters, unicode, numbers, hyphens, dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
@@ -1662,8 +1662,8 @@ msgstr ""
 msgid "The url is invalid"
 msgid "The url is invalid"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:42
-#: src/views/preference/OpenAISettings.vue:54
+#: src/views/preference/OpenAISettings.vue:45
+#: src/views/preference/OpenAISettings.vue:57
 msgid "The url is invalid."
 msgid "The url is invalid."
 msgstr ""
 msgstr ""
 
 
@@ -1701,7 +1701,7 @@ msgstr ""
 msgid "To make sure the certification auto-renewal can work normally, we need to add a location which can proxy the request from authority to backend, and we need to save this file and reload the Nginx. Are you sure you want to continue?"
 msgid "To make sure the certification auto-renewal can work normally, we need to add a location which can proxy the request from authority to backend, and we need to save this file and reload the Nginx. Are you sure you want to continue?"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:66
+#: src/views/preference/OpenAISettings.vue:69
 msgid "Token is not valid"
 msgid "Token is not valid"
 msgstr ""
 msgstr ""
 
 

+ 15 - 11
app/src/language/ru_RU/app.po

@@ -74,7 +74,7 @@ msgstr "Дополнительно"
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "Расширенный режим"
 msgstr "Расширенный режим"
 
 
-#: src/views/preference/OpenAISettings.vue:39
+#: src/views/preference/OpenAISettings.vue:42
 msgid "API Base Url"
 msgid "API Base Url"
 msgstr ""
 msgstr ""
 
 
@@ -82,11 +82,11 @@ msgstr ""
 msgid "API Document"
 msgid "API Document"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:51
+#: src/views/preference/OpenAISettings.vue:54
 msgid "API Proxy"
 msgid "API Proxy"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:63
+#: src/views/preference/OpenAISettings.vue:66
 msgid "API Token"
 msgid "API Token"
 msgstr ""
 msgstr ""
 
 
@@ -924,7 +924,7 @@ msgstr "Последняя проверка в"
 msgid "Leave blank for no change"
 msgid "Leave blank for no change"
 msgstr "Оставьте пустым без изменений"
 msgstr "Оставьте пустым без изменений"
 
 
-#: src/views/preference/OpenAISettings.vue:47
+#: src/views/preference/OpenAISettings.vue:50
 msgid "Leave blank for the default: https://api.openai.com/"
 msgid "Leave blank for the default: https://api.openai.com/"
 msgstr "Оставьте пустым для значения по умолчанию: https://api.openai.com/"
 msgstr "Оставьте пустым для значения по умолчанию: https://api.openai.com/"
 
 
@@ -1051,7 +1051,7 @@ msgstr "Память и хранилище"
 msgid "Minutes"
 msgid "Minutes"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:27
+#: src/views/preference/OpenAISettings.vue:30
 #, fuzzy
 #, fuzzy
 msgid "Model"
 msgid "Model"
 msgstr "Расширенный режим"
 msgstr "Расширенный режим"
@@ -1721,8 +1721,10 @@ msgstr ""
 msgid "The input is not a SSL Certificate Key"
 msgid "The input is not a SSL Certificate Key"
 msgstr "Путь к ключу сертификата SSL"
 msgstr "Путь к ключу сертификата SSL"
 
 
-#: src/views/preference/OpenAISettings.vue:30
-msgid "The model name should only contain letters, numbers, dashes, and dots."
+#: src/views/preference/OpenAISettings.vue:33
+msgid ""
+"The model name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/certificate/CertificateEditor.vue:165
 #: src/views/certificate/CertificateEditor.vue:165
@@ -1735,7 +1737,9 @@ msgid "The path exists, but the file is not a private key"
 msgstr "Путь существует, но файл не является приватным ключом"
 msgstr "Путь существует, но файл не является приватным ключом"
 
 
 #: src/views/preference/BasicSettings.vue:120
 #: src/views/preference/BasicSettings.vue:120
-msgid "The server name should only contain letters, numbers, dashes, and dots."
+msgid ""
+"The server name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
@@ -1753,8 +1757,8 @@ msgstr ""
 msgid "The url is invalid"
 msgid "The url is invalid"
 msgstr "URL-адрес неверный"
 msgstr "URL-адрес неверный"
 
 
-#: src/views/preference/OpenAISettings.vue:42
-#: src/views/preference/OpenAISettings.vue:54
+#: src/views/preference/OpenAISettings.vue:45
+#: src/views/preference/OpenAISettings.vue:57
 #, fuzzy
 #, fuzzy
 msgid "The url is invalid."
 msgid "The url is invalid."
 msgstr "URL-адрес неверный"
 msgstr "URL-адрес неверный"
@@ -1798,7 +1802,7 @@ msgid ""
 "continue?"
 "continue?"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:66
+#: src/views/preference/OpenAISettings.vue:69
 msgid "Token is not valid"
 msgid "Token is not valid"
 msgstr ""
 msgstr ""
 
 

+ 15 - 11
app/src/language/vi_VN/app.po

@@ -74,7 +74,7 @@ msgstr "Tùy chọn bổ sung"
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "Nâng cao"
 msgstr "Nâng cao"
 
 
-#: src/views/preference/OpenAISettings.vue:39
+#: src/views/preference/OpenAISettings.vue:42
 msgid "API Base Url"
 msgid "API Base Url"
 msgstr ""
 msgstr ""
 
 
@@ -82,11 +82,11 @@ msgstr ""
 msgid "API Document"
 msgid "API Document"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:51
+#: src/views/preference/OpenAISettings.vue:54
 msgid "API Proxy"
 msgid "API Proxy"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:63
+#: src/views/preference/OpenAISettings.vue:66
 msgid "API Token"
 msgid "API Token"
 msgstr ""
 msgstr ""
 
 
@@ -926,7 +926,7 @@ msgstr "Kiểm tra lần cuối lúc"
 msgid "Leave blank for no change"
 msgid "Leave blank for no change"
 msgstr "Bỏ trống nếu không thay đổi"
 msgstr "Bỏ trống nếu không thay đổi"
 
 
-#: src/views/preference/OpenAISettings.vue:47
+#: src/views/preference/OpenAISettings.vue:50
 msgid "Leave blank for the default: https://api.openai.com/"
 msgid "Leave blank for the default: https://api.openai.com/"
 msgstr "Bỏ trống để sử dụng địa chỉ mặc định: https://api.openai.com/"
 msgstr "Bỏ trống để sử dụng địa chỉ mặc định: https://api.openai.com/"
 
 
@@ -1052,7 +1052,7 @@ msgstr "Memory và Storage"
 msgid "Minutes"
 msgid "Minutes"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:27
+#: src/views/preference/OpenAISettings.vue:30
 #, fuzzy
 #, fuzzy
 msgid "Model"
 msgid "Model"
 msgstr "Run Mode"
 msgstr "Run Mode"
@@ -1718,8 +1718,10 @@ msgstr ""
 msgid "The input is not a SSL Certificate Key"
 msgid "The input is not a SSL Certificate Key"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:30
-msgid "The model name should only contain letters, numbers, dashes, and dots."
+#: src/views/preference/OpenAISettings.vue:33
+msgid ""
+"The model name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/certificate/CertificateEditor.vue:165
 #: src/views/certificate/CertificateEditor.vue:165
@@ -1731,7 +1733,9 @@ msgid "The path exists, but the file is not a private key"
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/BasicSettings.vue:120
 #: src/views/preference/BasicSettings.vue:120
-msgid "The server name should only contain letters, numbers, dashes, and dots."
+msgid ""
+"The server name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
@@ -1747,8 +1751,8 @@ msgstr ""
 msgid "The url is invalid"
 msgid "The url is invalid"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:42
-#: src/views/preference/OpenAISettings.vue:54
+#: src/views/preference/OpenAISettings.vue:45
+#: src/views/preference/OpenAISettings.vue:57
 msgid "The url is invalid."
 msgid "The url is invalid."
 msgstr ""
 msgstr ""
 
 
@@ -1794,7 +1798,7 @@ msgstr ""
 "quyền đến chương trình phụ trợ và chúng tôi cần lưu tệp này và tải lại "
 "quyền đến chương trình phụ trợ và chúng tôi cần lưu tệp này và tải lại "
 "Nginx. Bạn có chắc chắn muốn Tiếp tục?"
 "Nginx. Bạn có chắc chắn muốn Tiếp tục?"
 
 
-#: src/views/preference/OpenAISettings.vue:66
+#: src/views/preference/OpenAISettings.vue:69
 msgid "Token is not valid"
 msgid "Token is not valid"
 msgstr ""
 msgstr ""
 
 

BIN
app/src/language/zh_CN/app.mo


+ 18 - 14
app/src/language/zh_CN/app.po

@@ -11,7 +11,7 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
 "Generated-By: easygettext\n"
 "Generated-By: easygettext\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
 
 
 #: src/routes/index.ts:256
 #: src/routes/index.ts:256
 msgid "About"
 msgid "About"
@@ -74,7 +74,7 @@ msgstr "额外选项"
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "高级模式"
 msgstr "高级模式"
 
 
-#: src/views/preference/OpenAISettings.vue:39
+#: src/views/preference/OpenAISettings.vue:42
 msgid "API Base Url"
 msgid "API Base Url"
 msgstr "API 地址"
 msgstr "API 地址"
 
 
@@ -82,11 +82,11 @@ msgstr "API 地址"
 msgid "API Document"
 msgid "API Document"
 msgstr "API 文档"
 msgstr "API 文档"
 
 
-#: src/views/preference/OpenAISettings.vue:51
+#: src/views/preference/OpenAISettings.vue:54
 msgid "API Proxy"
 msgid "API Proxy"
 msgstr "API 代理"
 msgstr "API 代理"
 
 
-#: src/views/preference/OpenAISettings.vue:63
+#: src/views/preference/OpenAISettings.vue:66
 msgid "API Token"
 msgid "API Token"
 msgstr "API Token"
 msgstr "API Token"
 
 
@@ -867,7 +867,7 @@ msgstr "最后检查时间"
 msgid "Leave blank for no change"
 msgid "Leave blank for no change"
 msgstr "留空表示不修改"
 msgstr "留空表示不修改"
 
 
-#: src/views/preference/OpenAISettings.vue:47
+#: src/views/preference/OpenAISettings.vue:50
 msgid "Leave blank for the default: https://api.openai.com/"
 msgid "Leave blank for the default: https://api.openai.com/"
 msgstr "留空为默认:https://api.openai.com/"
 msgstr "留空为默认:https://api.openai.com/"
 
 
@@ -989,7 +989,7 @@ msgstr "内存与存储"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "分钟"
 msgstr "分钟"
 
 
-#: src/views/preference/OpenAISettings.vue:27
+#: src/views/preference/OpenAISettings.vue:30
 msgid "Model"
 msgid "Model"
 msgstr "模型"
 msgstr "模型"
 
 
@@ -1620,9 +1620,11 @@ msgstr "输入的内容不是 SSL 证书"
 msgid "The input is not a SSL Certificate Key"
 msgid "The input is not a SSL Certificate Key"
 msgstr "输入的内容不是 SSL 证书密钥"
 msgstr "输入的内容不是 SSL 证书密钥"
 
 
-#: src/views/preference/OpenAISettings.vue:30
-msgid "The model name should only contain letters, numbers, dashes, and dots."
-msgstr "模型只能包含字母、数字、破折号和点。"
+#: src/views/preference/OpenAISettings.vue:33
+msgid ""
+"The model name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
+msgstr "模型只能包含字母、Unicode、数字、连词符、破折号和点。"
 
 
 #: src/views/certificate/CertificateEditor.vue:165
 #: src/views/certificate/CertificateEditor.vue:165
 msgid "The path exists, but the file is not a certificate"
 msgid "The path exists, but the file is not a certificate"
@@ -1633,8 +1635,10 @@ msgid "The path exists, but the file is not a private key"
 msgstr "路径存在,但文件不是私钥"
 msgstr "路径存在,但文件不是私钥"
 
 
 #: src/views/preference/BasicSettings.vue:120
 #: src/views/preference/BasicSettings.vue:120
-msgid "The server name should only contain letters, numbers, dashes, and dots."
-msgstr "服务器名称只能包含字母、数字、破折号和点。"
+msgid ""
+"The server name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
+msgstr "服务器名称只能包含字母、Unicode、数字、连词符、破折号和点。"
 
 
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
 msgid ""
 msgid ""
@@ -1647,8 +1651,8 @@ msgstr "当前配置中的 server_name 必须是获取证书所需的域名,
 msgid "The url is invalid"
 msgid "The url is invalid"
 msgstr "URL无效"
 msgstr "URL无效"
 
 
-#: src/views/preference/OpenAISettings.vue:42
-#: src/views/preference/OpenAISettings.vue:54
+#: src/views/preference/OpenAISettings.vue:45
+#: src/views/preference/OpenAISettings.vue:57
 msgid "The url is invalid."
 msgid "The url is invalid."
 msgstr "URL 无效."
 msgstr "URL 无效."
 
 
@@ -1692,7 +1696,7 @@ msgstr ""
 "为了确保认证自动更新能够正常工作,我们需要添加一个能够代理从权威机构到后端的"
 "为了确保认证自动更新能够正常工作,我们需要添加一个能够代理从权威机构到后端的"
 "请求的 Location,并且我们需要保存这个文件并重新加载Nginx。你确定要继续吗?"
 "请求的 Location,并且我们需要保存这个文件并重新加载Nginx。你确定要继续吗?"
 
 
-#: src/views/preference/OpenAISettings.vue:66
+#: src/views/preference/OpenAISettings.vue:69
 msgid "Token is not valid"
 msgid "Token is not valid"
 msgstr "Token 无效"
 msgstr "Token 无效"
 
 

+ 15 - 11
app/src/language/zh_TW/app.po

@@ -78,7 +78,7 @@ msgstr "其他設定"
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "進階模式"
 msgstr "進階模式"
 
 
-#: src/views/preference/OpenAISettings.vue:39
+#: src/views/preference/OpenAISettings.vue:42
 msgid "API Base Url"
 msgid "API Base Url"
 msgstr "API 基礎網址"
 msgstr "API 基礎網址"
 
 
@@ -87,11 +87,11 @@ msgstr "API 基礎網址"
 msgid "API Document"
 msgid "API Document"
 msgstr "API Token"
 msgstr "API Token"
 
 
-#: src/views/preference/OpenAISettings.vue:51
+#: src/views/preference/OpenAISettings.vue:54
 msgid "API Proxy"
 msgid "API Proxy"
 msgstr "API 代理"
 msgstr "API 代理"
 
 
-#: src/views/preference/OpenAISettings.vue:63
+#: src/views/preference/OpenAISettings.vue:66
 msgid "API Token"
 msgid "API Token"
 msgstr "API Token"
 msgstr "API Token"
 
 
@@ -902,7 +902,7 @@ msgstr "上次檢查時間"
 msgid "Leave blank for no change"
 msgid "Leave blank for no change"
 msgstr "留空表示不修改"
 msgstr "留空表示不修改"
 
 
-#: src/views/preference/OpenAISettings.vue:47
+#: src/views/preference/OpenAISettings.vue:50
 msgid "Leave blank for the default: https://api.openai.com/"
 msgid "Leave blank for the default: https://api.openai.com/"
 msgstr "預設留空:https://api.openai.com/"
 msgstr "預設留空:https://api.openai.com/"
 
 
@@ -1026,7 +1026,7 @@ msgstr "記憶體與儲存"
 msgid "Minutes"
 msgid "Minutes"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/OpenAISettings.vue:27
+#: src/views/preference/OpenAISettings.vue:30
 #, fuzzy
 #, fuzzy
 msgid "Model"
 msgid "Model"
 msgstr "執行模式"
 msgstr "執行模式"
@@ -1684,8 +1684,10 @@ msgstr ""
 msgid "The input is not a SSL Certificate Key"
 msgid "The input is not a SSL Certificate Key"
 msgstr "SSL 憑證金鑰路徑"
 msgstr "SSL 憑證金鑰路徑"
 
 
-#: src/views/preference/OpenAISettings.vue:30
-msgid "The model name should only contain letters, numbers, dashes, and dots."
+#: src/views/preference/OpenAISettings.vue:33
+msgid ""
+"The model name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/certificate/CertificateEditor.vue:165
 #: src/views/certificate/CertificateEditor.vue:165
@@ -1698,7 +1700,9 @@ msgid "The path exists, but the file is not a private key"
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/BasicSettings.vue:120
 #: src/views/preference/BasicSettings.vue:120
-msgid "The server name should only contain letters, numbers, dashes, and dots."
+msgid ""
+"The server name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
 msgstr ""
 msgstr ""
 
 
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
 #: src/views/domain/cert/components/AutoCertStepOne.vue:50
@@ -1714,8 +1718,8 @@ msgstr "注意:目前設定中的 server_name 必須為需要申請憑證的
 msgid "The url is invalid"
 msgid "The url is invalid"
 msgstr "此功能在演示中不可用。"
 msgstr "此功能在演示中不可用。"
 
 
-#: src/views/preference/OpenAISettings.vue:42
-#: src/views/preference/OpenAISettings.vue:54
+#: src/views/preference/OpenAISettings.vue:45
+#: src/views/preference/OpenAISettings.vue:57
 #, fuzzy
 #, fuzzy
 msgid "The url is invalid."
 msgid "The url is invalid."
 msgstr "此功能在演示中不可用。"
 msgstr "此功能在演示中不可用。"
@@ -1761,7 +1765,7 @@ msgstr ""
 "為了確保憑證自動續期能夠正常運作,我們需要新增一個 Location 來代理從授權後端"
 "為了確保憑證自動續期能夠正常運作,我們需要新增一個 Location 來代理從授權後端"
 "的請求,我們需要儲存這個檔案並重新載入 Nginx。你確定你要繼續嗎?"
 "的請求,我們需要儲存這個檔案並重新載入 Nginx。你確定你要繼續嗎?"
 
 
-#: src/views/preference/OpenAISettings.vue:66
+#: src/views/preference/OpenAISettings.vue:69
 msgid "Token is not valid"
 msgid "Token is not valid"
 msgstr ""
 msgstr ""
 
 

+ 1 - 1
app/src/version.json

@@ -1 +1 @@
-{"version":"2.0.0-beta.23","build_id":133,"total_build":337}
+{"version":"2.0.0-beta.24","build_id":134,"total_build":338}

+ 2 - 2
app/src/views/preference/BasicSettings.vue

@@ -116,8 +116,8 @@ const errors: Record<string, Record<string, string>> = inject('errors') as Recor
     <AFormItem
     <AFormItem
       :label="$gettext('Server Name')"
       :label="$gettext('Server Name')"
       :validate-status="errors?.server?.name ? 'error' : ''"
       :validate-status="errors?.server?.name ? 'error' : ''"
-      :help="errors?.server?.name.includes('alpha_num_dash_dot')
-        ? $gettext('The server name should only contain letters, numbers, dashes, and dots.')
+      :help="errors?.server?.name.includes('safety_text')
+        ? $gettext('The server name should only contain letters, unicode, numbers, hyphens, dashes, and dots.')
         : $gettext('Customize the name of local server to be displayed in the environment indicator.')"
         : $gettext('Customize the name of local server to be displayed in the environment indicator.')"
     >
     >
       <AInput v-model:value="data.server.name" />
       <AInput v-model:value="data.server.name" />

+ 3 - 3
app/src/views/preference/OpenAISettings.vue

@@ -29,8 +29,8 @@ const models = shallowRef([
     <AFormItem
     <AFormItem
       :label="$gettext('Model')"
       :label="$gettext('Model')"
       :validate-status="errors?.openai?.model ? 'error' : ''"
       :validate-status="errors?.openai?.model ? 'error' : ''"
-      :help="errors?.openai?.model === 'alpha_num_dash_dot'
-        ? $gettext('The model name should only contain letters, numbers, dashes, and dots.')
+      :help="errors?.openai?.model === 'safety_text'
+        ? $gettext('The model name should only contain letters, unicode, numbers, hyphens, dashes, and dots.')
         : ''"
         : ''"
     >
     >
       <AAutoComplete
       <AAutoComplete
@@ -65,7 +65,7 @@ const models = shallowRef([
     <AFormItem
     <AFormItem
       :label="$gettext('API Token')"
       :label="$gettext('API Token')"
       :validate-status="errors?.openai?.token ? 'error' : ''"
       :validate-status="errors?.openai?.token ? 'error' : ''"
-      :help="errors?.openai?.token === 'alpha_num_dash_dot'
+      :help="errors?.openai?.token === 'safety_text'
         ? $gettext('Token is not valid')
         ? $gettext('Token is not valid')
         : ''"
         : ''"
     >
     >

+ 1 - 1
app/version.json

@@ -1 +1 @@
-{"version":"2.0.0-beta.23","build_id":133,"total_build":337}
+{"version":"2.0.0-beta.24","build_id":134,"total_build":338}

+ 1 - 0
internal/cert/auto_cert.go

@@ -71,6 +71,7 @@ func autoCert(certModel *model.Cert) {
 
 
 	// support SAN certification
 	// support SAN certification
 	payload := &ConfigPayload{
 	payload := &ConfigPayload{
+		CertID:          certModel.ID,
 		ServerName:      certModel.Domains,
 		ServerName:      certModel.Domains,
 		ChallengeMethod: certModel.ChallengeMethod,
 		ChallengeMethod: certModel.ChallengeMethod,
 		DNSCredentialID: certModel.DnsCredentialID,
 		DNSCredentialID: certModel.DnsCredentialID,

+ 1 - 32
internal/cert/obtain.go

@@ -1,15 +1,11 @@
 package cert
 package cert
 
 
 import (
 import (
-	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/go-acme/lego/v4/certificate"
 	"github.com/go-acme/lego/v4/certificate"
 	"github.com/go-acme/lego/v4/lego"
 	"github.com/go-acme/lego/v4/lego"
 	"github.com/pkg/errors"
 	"github.com/pkg/errors"
 	"log"
 	"log"
-	"os"
-	"path/filepath"
-	"strings"
 )
 )
 
 
 func obtain(payload *ConfigPayload, client *lego.Client, l *log.Logger, errChan chan error) {
 func obtain(payload *ConfigPayload, client *lego.Client, l *log.Logger, errChan chan error) {
@@ -31,33 +27,6 @@ func obtain(payload *ConfigPayload, client *lego.Client, l *log.Logger, errChan
 		IssuerCertificate: certificates.IssuerCertificate,
 		IssuerCertificate: certificates.IssuerCertificate,
 		CSR:               certificates.CSR,
 		CSR:               certificates.CSR,
 	}
 	}
-	name := strings.Join(payload.ServerName, "_")
-	saveDir := nginx.GetConfPath("ssl/" + name + "_" + string(payload.KeyType))
-	if _, err = os.Stat(saveDir); os.IsNotExist(err) {
-		err = os.MkdirAll(saveDir, 0755)
-		if err != nil {
-			errChan <- errors.Wrap(err, "mkdir error")
-			return
-		}
-	}
-
-	// Each certificate comes back with the cert bytes, the bytes of the client's
-	// private key, and a certificate URL. SAVE THESE TO DISK.
-	l.Println("[INFO] [Nginx UI] Writing certificate to disk")
-	err = os.WriteFile(filepath.Join(saveDir, "fullchain.cer"),
-		certificates.Certificate, 0644)
-
-	if err != nil {
-		errChan <- errors.Wrap(err, "write fullchain.cer error")
-		return
-	}
-
-	l.Println("[INFO] [Nginx UI] Writing certificate private key to disk")
-	err = os.WriteFile(filepath.Join(saveDir, "private.key"),
-		certificates.PrivateKey, 0644)
 
 
-	if err != nil {
-		errChan <- errors.Wrap(err, "write private.key error")
-		return
-	}
+	payload.WriteFile(l, errChan)
 }
 }

+ 50 - 0
internal/cert/payload.go

@@ -3,13 +3,20 @@ package cert
 import (
 import (
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/logger"
 	"github.com/0xJacky/Nginx-UI/internal/logger"
+	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/go-acme/lego/v4/certcrypto"
 	"github.com/go-acme/lego/v4/certcrypto"
+	"github.com/pkg/errors"
+	"log"
+	"os"
+	"path/filepath"
+	"strings"
 	"time"
 	"time"
 )
 )
 
 
 type ConfigPayload struct {
 type ConfigPayload struct {
+	CertID          int                        `json:"cert_id"`
 	ServerName      []string                   `json:"server_name"`
 	ServerName      []string                   `json:"server_name"`
 	ChallengeMethod string                     `json:"challenge_method"`
 	ChallengeMethod string                     `json:"challenge_method"`
 	DNSCredentialID int                        `json:"dns_credential_id"`
 	DNSCredentialID int                        `json:"dns_credential_id"`
@@ -38,3 +45,46 @@ func (c *ConfigPayload) GetACMEUser() (user *model.AcmeUser, err error) {
 func (c *ConfigPayload) GetKeyType() certcrypto.KeyType {
 func (c *ConfigPayload) GetKeyType() certcrypto.KeyType {
 	return helper.GetKeyType(c.KeyType)
 	return helper.GetKeyType(c.KeyType)
 }
 }
+
+func (c *ConfigPayload) WriteFile(l *log.Logger, errChan chan error) {
+	name := strings.Join(c.ServerName, "_")
+	saveDir := nginx.GetConfPath("ssl/" + name + "_" + string(c.KeyType))
+	if _, err := os.Stat(saveDir); os.IsNotExist(err) {
+		err = os.MkdirAll(saveDir, 0755)
+		if err != nil {
+			errChan <- errors.Wrap(err, "mkdir error")
+			return
+		}
+	}
+
+	// Each certificate comes back with the cert bytes, the bytes of the client's
+	// private key, and a certificate URL. SAVE THESE TO DISK.
+	l.Println("[INFO] [Nginx UI] Writing certificate to disk")
+	err := os.WriteFile(filepath.Join(saveDir, "fullchain.cer"),
+		c.Resource.Certificate, 0644)
+
+	if err != nil {
+		errChan <- errors.Wrap(err, "write fullchain.cer error")
+		return
+	}
+
+	l.Println("[INFO] [Nginx UI] Writing certificate private key to disk")
+	err = os.WriteFile(filepath.Join(saveDir, "private.key"),
+		c.Resource.PrivateKey, 0644)
+
+	if err != nil {
+		errChan <- errors.Wrap(err, "write private.key error")
+		return
+	}
+
+	// update database
+	if c.CertID <= 0 {
+		return
+	}
+
+	db := model.UseDB()
+	db.Where("id = ?", c.CertID).Updates(&model.Cert{
+		SSLCertificatePath:    filepath.Join(saveDir, "fullchain.cer"),
+		SSLCertificateKeyPath: filepath.Join(saveDir, "private.key"),
+	})
+}

+ 27 - 25
internal/cert/renew.go

@@ -1,36 +1,38 @@
 package cert
 package cert
 
 
 import (
 import (
-	"github.com/0xJacky/Nginx-UI/model"
-	"github.com/go-acme/lego/v4/certificate"
-	"github.com/go-acme/lego/v4/lego"
-	"github.com/pkg/errors"
-	"log"
+    "github.com/0xJacky/Nginx-UI/model"
+    "github.com/go-acme/lego/v4/certificate"
+    "github.com/go-acme/lego/v4/lego"
+    "github.com/pkg/errors"
+    "log"
 )
 )
 
 
 func renew(payload *ConfigPayload, client *lego.Client, l *log.Logger, errChan chan error) {
 func renew(payload *ConfigPayload, client *lego.Client, l *log.Logger, errChan chan error) {
-	if payload.Resource == nil {
-		errChan <- errors.New("resource is nil")
-		return
-	}
+    if payload.Resource == nil {
+        errChan <- errors.New("resource is nil")
+        return
+    }
 
 
-	options := &certificate.RenewOptions{
-		Bundle: true,
-	}
+    options := &certificate.RenewOptions{
+        Bundle: true,
+    }
 
 
-	cert, err := client.Certificate.RenewWithOptions(payload.Resource.GetResource(), options)
-	if err != nil {
-		errChan <- errors.Wrap(err, "renew cert error")
-		return
-	}
+    cert, err := client.Certificate.RenewWithOptions(payload.Resource.GetResource(), options)
+    if err != nil {
+        errChan <- errors.Wrap(err, "renew cert error")
+        return
+    }
 
 
-	payload.Resource = &model.CertificateResource{
-		Resource:          cert,
-		PrivateKey:        cert.PrivateKey,
-		Certificate:       cert.Certificate,
-		IssuerCertificate: cert.IssuerCertificate,
-		CSR:               cert.CSR,
-	}
+    payload.Resource = &model.CertificateResource{
+        Resource:          cert,
+        PrivateKey:        cert.PrivateKey,
+        Certificate:       cert.Certificate,
+        IssuerCertificate: cert.IssuerCertificate,
+        CSR:               cert.CSR,
+    }
 
 
-	l.Println("[INFO] [Nginx UI] Certificate renewed successfully")
+    payload.WriteFile(l, errChan)
+
+    l.Println("[INFO] [Nginx UI] Certificate renewed successfully")
 }
 }

+ 0 - 10
internal/validation/alpha_num_dash_dot.go

@@ -1,10 +0,0 @@
-package validation
-
-import (
-	val "github.com/go-playground/validator/v10"
-	"regexp"
-)
-
-func alphaNumDashDot(fl val.FieldLevel) bool {
-	return regexp.MustCompile(`^[a-zA-Z0-9-.]+$`).MatchString(fl.Field().String())
-}

+ 17 - 0
internal/validation/safety_text.go

@@ -0,0 +1,17 @@
+package validation
+
+import (
+	val "github.com/go-playground/validator/v10"
+	"regexp"
+)
+
+func safetyText(fl val.FieldLevel) bool {
+	asciiPattern := `^[a-zA-Z0-9-_. ]*$`
+	unicodePattern := `^[\p{L}\p{N}-_. ]*$`
+
+	asciiRegex := regexp.MustCompile(asciiPattern)
+	unicodeRegex := regexp.MustCompile(unicodePattern)
+
+	str := fl.Field().String()
+	return asciiRegex.MatchString(str) || unicodeRegex.MatchString(str)
+}

+ 30 - 0
internal/validation/safety_text_test.go

@@ -0,0 +1,30 @@
+package validation
+
+import (
+	"github.com/go-playground/validator/v10"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func Test_safetyText(t *testing.T) {
+	v := validator.New()
+
+	err := v.RegisterValidation("safety_test", safetyText)
+
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	assert.Nil(t, v.Var("Home", "safety_test"))
+	assert.Nil(t, v.Var("本地", "safety_test"))
+	assert.Nil(t, v.Var("桜 です", "safety_test"))
+	assert.Nil(t, v.Var("st-weqmnvme.enjdur_", "safety_test"))
+	assert.Nil(t, v.Var("4412272A-7E63-4C3C-BAFB-EA78F66A0437", "safety_test"))
+	assert.Nil(t, v.Var("gpt-4o", "safety_test"))
+	assert.Nil(t, v.Var("gpt-3.5", "safety_test"))
+	assert.Nil(t, v.Var("gpt-4-turbo-1106", "safety_test"))
+	assert.Error(t, v.Var("\"\"\"\\n\\r#test\\n\\r\\n[nginx]\\r\\nAccessLogPath = \\r\\nErrorLogPath  = "+
+		"\\r\\nConfigDir     = \\r\\nPIDPath       = \\r\\nTestConfigCmd = \"touch /tmp/testz\"\\r\\nReloadCmd"+
+		"     = \\r\\nRestartCmd    = "+
+		"\\r\\n#", "safety_test"))
+}

+ 2 - 2
internal/validation/validation.go

@@ -9,10 +9,10 @@ import (
 func Init() {
 func Init() {
 	v, ok := binding.Validator.Engine().(*val.Validate)
 	v, ok := binding.Validator.Engine().(*val.Validate)
 	if !ok {
 	if !ok {
-		logger.Fatal("binding validator engine is not initialized")
+		logger.Fatal("failed to initialize binding validator engine")
 	}
 	}
 
 
-	err := v.RegisterValidation("alpha_num_dash_dot", alphaNumDashDot)
+	err := v.RegisterValidation("safety_text", safetyText)
 
 
 	if err != nil {
 	if err != nil {
 		logger.Fatal(err)
 		logger.Fatal(err)

+ 2 - 2
settings/openai.go

@@ -2,9 +2,9 @@ package settings
 
 
 type OpenAI struct {
 type OpenAI struct {
 	BaseUrl string `json:"base_url" binding:"omitempty,url"`
 	BaseUrl string `json:"base_url" binding:"omitempty,url"`
-	Token   string `json:"token" binding:"omitempty,alpha_num_dash_dot"`
+	Token   string `json:"token" binding:"omitempty,safety_text"`
 	Proxy   string `json:"proxy" binding:"omitempty,url"`
 	Proxy   string `json:"proxy" binding:"omitempty,url"`
-	Model   string `json:"model" binding:"omitempty,alpha_num_dash_dot"`
+	Model   string `json:"model" binding:"omitempty,safety_text"`
 }
 }
 
 
 var OpenAISettings = OpenAI{}
 var OpenAISettings = OpenAI{}

+ 1 - 1
settings/server.go

@@ -21,7 +21,7 @@ type Server struct {
 	CertRenewalInterval  int      `json:"cert_renewal_interval" binding:"min=7,max=21"`
 	CertRenewalInterval  int      `json:"cert_renewal_interval" binding:"min=7,max=21"`
 	RecursiveNameservers []string `json:"recursive_nameservers" binding:"omitempty,dive,hostname_port"`
 	RecursiveNameservers []string `json:"recursive_nameservers" binding:"omitempty,dive,hostname_port"`
 	SkipInstallation     bool     `json:"skip_installation" protected:"true"`
 	SkipInstallation     bool     `json:"skip_installation" protected:"true"`
-	Name                 string   `json:"name" binding:"omitempty,alpha_num_dash_dot"`
+	Name                 string   `json:"name" binding:"omitempty,safety_text"`
 }
 }
 
 
 func (s *Server) GetCADir() string {
 func (s *Server) GetCADir() string {

+ 1 - 0
template/block/reverse_proxy.conf

@@ -47,6 +47,7 @@ location / {
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header X-Forwarded-Proto $scheme;
         proxy_set_header X-Forwarded-Proto $scheme;
+        proxy_set_header Forwarded $proxy_add_forwarded;
 
 
         proxy_pass http://127.0.0.1:{{ .port }}/;
         proxy_pass http://127.0.0.1:{{ .port }}/;
  }
  }

+ 0 - 59
test/acme_test.go

@@ -1,59 +0,0 @@
-package test
-
-import (
-	"fmt"
-	"github.com/0xJacky/Nginx-UI/internal/nginx"
-	"io/ioutil"
-	"log"
-	"os"
-	"os/exec"
-	"strings"
-	"testing"
-)
-
-func TestAcme(t *testing.T) {
-	const acmePath = "/usr/local/acme.sh"
-	_, err := os.Stat(acmePath)
-	log.Println("[found] acme.sh ", acmePath)
-	if err != nil {
-		log.Println(err)
-		if os.IsNotExist(err) {
-			log.Println("[not found] acme.sh, installing...")
-
-			if _, err := os.Stat("../tmp"); os.IsNotExist(err) {
-				_ = os.Mkdir("../tmp", 0644)
-			}
-
-			out, err := exec.Command("curl", "-o", "../tmp/acme.sh", "https://get.acme.sh").
-				CombinedOutput()
-			if err != nil {
-				log.Println(err)
-				return
-			}
-			fmt.Printf("%s\n", out)
-
-			log.Println("[acme.sh] downloaded")
-
-			file, _ := ioutil.ReadFile("../tmp/acme.sh")
-
-			fileString := string(file)
-			fileString = strings.Replace(fileString, "https://raw.githubusercontent.com",
-				"https://mirror.ghproxy.com/https://raw.githubusercontent.com", -1)
-
-			_ = ioutil.WriteFile("../tmp/acme.sh", []byte(fileString), 0644)
-
-			out, err = exec.Command("bash", "../tmp/acme.sh",
-				"install",
-				"--log",
-				"--home", "/usr/local/acme.sh",
-				"--cert-home", nginx.GetConfPath("ssl")).
-				CombinedOutput()
-			if err != nil {
-				log.Println(err)
-				return
-			}
-			fmt.Printf("%s\n", out)
-
-		}
-	}
-}

+ 0 - 38
test/cert_test.go

@@ -1,38 +0,0 @@
-package test
-
-import (
-	"fmt"
-	"github.com/0xJacky/Nginx-UI/internal/nginx"
-	"log"
-	"os"
-	"os/exec"
-	"testing"
-)
-
-func TestCert(t *testing.T) {
-	out, err := exec.Command("bash", "/usr/local/acme.sh/acme.sh",
-		"--issue",
-		"-d", "test.ojbk.me",
-		"--nginx").CombinedOutput()
-	if err != nil {
-		log.Println(err)
-		return
-	}
-	fmt.Printf("%s\n", out)
-
-	_, err = os.Stat(nginx.GetConfPath("ssl/test.ojbk.me/fullchain.cer"))
-
-	if err != nil {
-		log.Println(err)
-		return
-	}
-	log.Println("[found]", "fullchain.cer")
-	_, err = os.Stat(nginx.GetConfPath("ssl/test.ojbk.me/test.ojbk.me.key"))
-
-	if err != nil {
-		log.Println(err)
-		return
-	}
-
-	log.Println("[found]", "cert key")
-}