From cb3599e721dcbff3c45b8b9176be26bf578d6166 Mon Sep 17 00:00:00 2001 From: Jacky Date: Sun, 15 Sep 2024 11:57:16 +0800 Subject: [PATCH] feat: copy secret to register otp #551 --- api/user/otp.go | 387 +++++++++---------- app/src/language/en/app.po | 44 ++- app/src/language/es/app.po | 44 ++- app/src/language/fr_FR/app.po | 44 ++- app/src/language/ko_KR/app.po | 44 ++- app/src/language/messages.pot | 44 ++- app/src/language/ru_RU/app.po | 44 ++- app/src/language/vi_VN/app.po | 44 ++- app/src/language/zh_CN/app.mo | Bin 33550 -> 33694 bytes app/src/language/zh_CN/app.po | 44 ++- app/src/language/zh_TW/app.po | 44 ++- app/src/views/preference/components/TOTP.vue | 17 +- 12 files changed, 434 insertions(+), 366 deletions(-) diff --git a/api/user/otp.go b/api/user/otp.go index f7c23644..49e1cb55 100644 --- a/api/user/otp.go +++ b/api/user/otp.go @@ -1,245 +1,228 @@ package user import ( - "bytes" - "crypto/sha1" - "encoding/base64" - "encoding/hex" - "fmt" - "github.com/0xJacky/Nginx-UI/api" - "github.com/0xJacky/Nginx-UI/internal/crypto" - "github.com/0xJacky/Nginx-UI/internal/user" - "github.com/0xJacky/Nginx-UI/model" - "github.com/0xJacky/Nginx-UI/query" - "github.com/0xJacky/Nginx-UI/settings" - "github.com/gin-gonic/gin" - "github.com/pquerna/otp" - "github.com/pquerna/otp/totp" - "image/jpeg" - "net/http" - "strings" + "bytes" + "crypto/sha1" + "encoding/base64" + "encoding/hex" + "fmt" + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/crypto" + "github.com/0xJacky/Nginx-UI/internal/user" + "github.com/0xJacky/Nginx-UI/model" + "github.com/0xJacky/Nginx-UI/query" + "github.com/0xJacky/Nginx-UI/settings" + "github.com/gin-gonic/gin" + "github.com/pquerna/otp" + "github.com/pquerna/otp/totp" + "image/jpeg" + "net/http" + "strings" ) func GenerateTOTP(c *gin.Context) { - u := api.CurrentUser(c) + u := api.CurrentUser(c) - issuer := fmt.Sprintf("Nginx UI %s", settings.ServerSettings.Name) - issuer = strings.TrimSpace(issuer) + issuer := fmt.Sprintf("Nginx UI %s", settings.ServerSettings.Name) + issuer = strings.TrimSpace(issuer) - otpOpts := totp.GenerateOpts{ - Issuer: issuer, - AccountName: u.Name, - Period: 30, // seconds - Digits: otp.DigitsSix, - Algorithm: otp.AlgorithmSHA1, - } - otpKey, err := totp.Generate(otpOpts) - if err != nil { - api.ErrHandler(c, err) - return - } - ciphertext, err := crypto.AesEncrypt([]byte(otpKey.Secret())) - if err != nil { - api.ErrHandler(c, err) - return - } + otpOpts := totp.GenerateOpts{ + Issuer: issuer, + AccountName: u.Name, + Period: 30, // seconds + Digits: otp.DigitsSix, + Algorithm: otp.AlgorithmSHA1, + } + otpKey, err := totp.Generate(otpOpts) + if err != nil { + api.ErrHandler(c, err) + return + } - qrCode, err := otpKey.Image(512, 512) - if err != nil { - api.ErrHandler(c, err) - return - } + qrCode, err := otpKey.Image(512, 512) + if err != nil { + api.ErrHandler(c, err) + return + } - // Encode the image to a buffer - var buf []byte - buffer := bytes.NewBuffer(buf) - err = jpeg.Encode(buffer, qrCode, nil) - if err != nil { - fmt.Println("Error encoding image:", err) - return - } + // Encode the image to a buffer + var buf []byte + buffer := bytes.NewBuffer(buf) + err = jpeg.Encode(buffer, qrCode, nil) + if err != nil { + fmt.Println("Error encoding image:", err) + return + } - // Convert the buffer to a base64 string - base64Str := "data:image/jpeg;base64," + base64.StdEncoding.EncodeToString(buffer.Bytes()) + // Convert the buffer to a base64 string + base64Str := "data:image/jpeg;base64," + base64.StdEncoding.EncodeToString(buffer.Bytes()) - c.JSON(http.StatusOK, gin.H{ - "secret": base64.StdEncoding.EncodeToString(ciphertext), - "qr_code": base64Str, - }) + c.JSON(http.StatusOK, gin.H{ + "secret": otpKey.Secret(), + "qr_code": base64Str, + }) } func EnrollTOTP(c *gin.Context) { - cUser := api.CurrentUser(c) - if cUser.EnabledOTP() { - c.JSON(http.StatusBadRequest, gin.H{ - "message": "User already enrolled", - }) - return - } + cUser := api.CurrentUser(c) + if cUser.EnabledOTP() { + c.JSON(http.StatusBadRequest, gin.H{ + "message": "User already enrolled", + }) + return + } - if settings.ServerSettings.Demo { - c.JSON(http.StatusBadRequest, gin.H{ - "message": "This feature is disabled in demo mode", - }) - return - } + if settings.ServerSettings.Demo { + c.JSON(http.StatusBadRequest, gin.H{ + "message": "This feature is disabled in demo mode", + }) + return + } - var json struct { - Secret string `json:"secret" binding:"required"` - Passcode string `json:"passcode" binding:"required"` - } - if !api.BindAndValid(c, &json) { - return - } + var json struct { + Secret string `json:"secret" binding:"required"` + Passcode string `json:"passcode" binding:"required"` + } + if !api.BindAndValid(c, &json) { + return + } - secret, err := base64.StdEncoding.DecodeString(json.Secret) - if err != nil { - api.ErrHandler(c, err) - return - } + if ok := totp.Validate(json.Passcode, json.Secret); !ok { + c.JSON(http.StatusNotAcceptable, gin.H{ + "message": "Invalid passcode", + }) + return + } - decrypted, err := crypto.AesDecrypt(secret) - if err != nil { - api.ErrHandler(c, err) - return - } + ciphertext, err := crypto.AesEncrypt([]byte(json.Secret)) + if err != nil { + api.ErrHandler(c, err) + return + } - if ok := totp.Validate(json.Passcode, string(decrypted)); !ok { - c.JSON(http.StatusNotAcceptable, gin.H{ - "message": "Invalid passcode", - }) - return - } + u := query.Auth + _, err = u.Where(u.ID.Eq(cUser.ID)).Update(u.OTPSecret, ciphertext) + if err != nil { + api.ErrHandler(c, err) + return + } - ciphertext, err := crypto.AesEncrypt(decrypted) - if err != nil { - api.ErrHandler(c, err) - return - } + recoveryCode := sha1.Sum(ciphertext) - u := query.Auth - _, err = u.Where(u.ID.Eq(cUser.ID)).Update(u.OTPSecret, ciphertext) - if err != nil { - api.ErrHandler(c, err) - return - } - - recoveryCode := sha1.Sum(ciphertext) - - c.JSON(http.StatusOK, gin.H{ - "message": "ok", - "recovery_code": hex.EncodeToString(recoveryCode[:]), - }) + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + "recovery_code": hex.EncodeToString(recoveryCode[:]), + }) } func ResetOTP(c *gin.Context) { - var json struct { - RecoveryCode string `json:"recovery_code"` - } - if !api.BindAndValid(c, &json) { - return - } - recoverCode, err := hex.DecodeString(json.RecoveryCode) - if err != nil { - api.ErrHandler(c, err) - return - } - cUser := api.CurrentUser(c) - k := sha1.Sum(cUser.OTPSecret) - if !bytes.Equal(k[:], recoverCode) { - c.JSON(http.StatusBadRequest, gin.H{ - "message": "Invalid recovery code", - }) - return - } + var json struct { + RecoveryCode string `json:"recovery_code"` + } + if !api.BindAndValid(c, &json) { + return + } + recoverCode, err := hex.DecodeString(json.RecoveryCode) + if err != nil { + api.ErrHandler(c, err) + return + } + cUser := api.CurrentUser(c) + k := sha1.Sum(cUser.OTPSecret) + if !bytes.Equal(k[:], recoverCode) { + c.JSON(http.StatusBadRequest, gin.H{ + "message": "Invalid recovery code", + }) + return + } - u := query.Auth - _, err = u.Where(u.ID.Eq(cUser.ID)).UpdateSimple(u.OTPSecret.Null()) - if err != nil { - api.ErrHandler(c, err) - return - } + u := query.Auth + _, err = u.Where(u.ID.Eq(cUser.ID)).UpdateSimple(u.OTPSecret.Null()) + if err != nil { + api.ErrHandler(c, err) + return + } - c.JSON(http.StatusOK, gin.H{ - "message": "ok", - }) + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) } func OTPStatus(c *gin.Context) { - status := false - u, ok := c.Get("user") - if ok { - status = u.(*model.Auth).EnabledOTP() - } - c.JSON(http.StatusOK, gin.H{ - "status": status, - }) + status := false + u, ok := c.Get("user") + if ok { + status = u.(*model.Auth).EnabledOTP() + } + c.JSON(http.StatusOK, gin.H{ + "status": status, + }) } func SecureSessionStatus(c *gin.Context) { - u, ok := c.Get("user") - if !ok || !u.(*model.Auth).EnabledOTP() { - c.JSON(http.StatusOK, gin.H{ - "status": false, - }) - return - } - ssid := c.GetHeader("X-Secure-Session-ID") - if ssid == "" { - ssid = c.Query("X-Secure-Session-ID") - } - if ssid == "" { - c.JSON(http.StatusOK, gin.H{ - "status": false, - }) - return - } + u, ok := c.Get("user") + if !ok || !u.(*model.Auth).EnabledOTP() { + c.JSON(http.StatusOK, gin.H{ + "status": false, + }) + return + } + ssid := c.GetHeader("X-Secure-Session-ID") + if ssid == "" { + ssid = c.Query("X-Secure-Session-ID") + } + if ssid == "" { + c.JSON(http.StatusOK, gin.H{ + "status": false, + }) + return + } - if user.VerifySecureSessionID(ssid, u.(*model.Auth).ID) { - c.JSON(http.StatusOK, gin.H{ - "status": true, - }) - return - } + if user.VerifySecureSessionID(ssid, u.(*model.Auth).ID) { + c.JSON(http.StatusOK, gin.H{ + "status": true, + }) + return + } - c.JSON(http.StatusOK, gin.H{ - "status": false, - }) + c.JSON(http.StatusOK, gin.H{ + "status": false, + }) } func StartSecure2FASession(c *gin.Context) { - var json struct { - OTP string `json:"otp"` - RecoveryCode string `json:"recovery_code"` - } - if !api.BindAndValid(c, &json) { - return - } - u := api.CurrentUser(c) - if !u.EnabledOTP() { - c.JSON(http.StatusBadRequest, gin.H{ - "message": "User not configured with 2FA", - }) - return - } + var json struct { + OTP string `json:"otp"` + RecoveryCode string `json:"recovery_code"` + } + if !api.BindAndValid(c, &json) { + return + } + u := api.CurrentUser(c) + if !u.EnabledOTP() { + c.JSON(http.StatusBadRequest, gin.H{ + "message": "User not configured with 2FA", + }) + return + } - if json.OTP == "" && json.RecoveryCode == "" { - c.JSON(http.StatusBadRequest, LoginResponse{ - Message: "The user has enabled 2FA", - }) - return - } + if json.OTP == "" && json.RecoveryCode == "" { + c.JSON(http.StatusBadRequest, LoginResponse{ + Message: "The user has enabled 2FA", + }) + return + } - if err := user.VerifyOTP(u, json.OTP, json.RecoveryCode); err != nil { - c.JSON(http.StatusBadRequest, LoginResponse{ - Message: "Invalid 2FA or recovery code", - }) - return - } + if err := user.VerifyOTP(u, json.OTP, json.RecoveryCode); err != nil { + c.JSON(http.StatusBadRequest, LoginResponse{ + Message: "Invalid 2FA or recovery code", + }) + return + } - sessionId := user.SetSecureSessionID(u.ID) + sessionId := user.SetSecureSessionID(u.ID) - c.JSON(http.StatusOK, gin.H{ - "session_id": sessionId, - }) + c.JSON(http.StatusOK, gin.H{ + "session_id": sessionId, + }) } diff --git a/app/src/language/en/app.po b/app/src/language/en/app.po index a9b23fb0..e574c55a 100644 --- a/app/src/language/en/app.po +++ b/app/src/language/en/app.po @@ -13,7 +13,7 @@ msgstr "" msgid "2FA" msgstr "" -#: src/views/preference/components/TOTP.vue:88 +#: src/views/preference/components/TOTP.vue:90 msgid "2FA Settings" msgstr "" @@ -259,6 +259,10 @@ msgstr "" msgid "CADir" msgstr "" +#: src/views/preference/components/TOTP.vue:150 +msgid "Can't scan? Use text key binding" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:252 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:55 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:253 @@ -452,11 +456,11 @@ msgstr "" msgid "Credentials" msgstr "" -#: src/views/preference/components/TOTP.vue:96 +#: src/views/preference/components/TOTP.vue:98 msgid "Current account is enabled 2FA." msgstr "" -#: src/views/preference/components/TOTP.vue:93 +#: src/views/preference/components/TOTP.vue:95 msgid "Current account is not enabled 2FA." msgstr "" @@ -753,12 +757,12 @@ msgstr "" msgid "Enable %{conf_name} in %{node_name} successfully" msgstr "" -#: src/views/preference/components/TOTP.vue:122 +#: src/views/preference/components/TOTP.vue:124 #, fuzzy msgid "Enable 2FA" msgstr "Enabled" -#: src/views/preference/components/TOTP.vue:52 +#: src/views/preference/components/TOTP.vue:54 #, fuzzy msgid "Enable 2FA successfully" msgstr "Enabled successfully" @@ -976,7 +980,7 @@ msgid "" "ban threshold minutes, the ip will be banned for a period of time." msgstr "" -#: src/views/preference/components/TOTP.vue:108 +#: src/views/preference/components/TOTP.vue:110 msgid "" "If you lose your mobile phone, you can use the recovery code to reset your " "2FA." @@ -1013,12 +1017,12 @@ msgstr "" msgid "Initialing core upgrader" msgstr "" -#: src/views/preference/components/TOTP.vue:144 +#: src/views/preference/components/TOTP.vue:157 msgid "Input the code from the app:" msgstr "" #: src/components/OTP/OTPAuthorization.vue:49 -#: src/views/preference/components/TOTP.vue:157 +#: src/views/preference/components/TOTP.vue:170 msgid "Input the recovery code:" msgstr "" @@ -1631,15 +1635,15 @@ msgid "Recovered Successfully" msgstr "Saved successfully" #: src/components/OTP/OTPAuthorization.vue:56 -#: src/views/preference/components/TOTP.vue:164 +#: src/views/preference/components/TOTP.vue:177 msgid "Recovery" msgstr "" -#: src/views/preference/components/TOTP.vue:101 +#: src/views/preference/components/TOTP.vue:103 msgid "Recovery Code" msgstr "" -#: src/views/preference/components/TOTP.vue:110 +#: src/views/preference/components/TOTP.vue:112 msgid "Recovery Code:" msgstr "" @@ -1779,7 +1783,7 @@ msgstr "" msgid "Reset" msgstr "" -#: src/views/preference/components/TOTP.vue:130 +#: src/views/preference/components/TOTP.vue:132 msgid "Reset 2FA" msgstr "" @@ -1832,7 +1836,7 @@ msgstr "Saved successfully" msgid "Saved successfully" msgstr "Saved successfully" -#: src/views/preference/components/TOTP.vue:91 +#: src/views/preference/components/TOTP.vue:93 msgid "Scan the QR code with your mobile phone to add the account to the app." msgstr "" @@ -1840,6 +1844,10 @@ msgstr "" msgid "SDK" msgstr "" +#: src/views/preference/components/TOTP.vue:149 +msgid "Secret has been copied" +msgstr "" + #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:155 msgid "Selector" msgstr "" @@ -1862,8 +1870,8 @@ msgstr "Send" #: src/views/environment/BatchUpgrader.vue:57 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68 #: src/views/preference/AuthSettings.vue:49 -#: src/views/preference/components/TOTP.vue:42 -#: src/views/preference/components/TOTP.vue:55 +#: src/views/preference/components/TOTP.vue:44 +#: src/views/preference/components/TOTP.vue:57 #: src/views/preference/Preference.vue:83 src/views/stream/StreamList.vue:113 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42 msgid "Server error" @@ -2112,7 +2120,7 @@ msgstr "Certificate Status" msgid "The path exists, but the file is not a private key" msgstr "" -#: src/views/preference/components/TOTP.vue:109 +#: src/views/preference/components/TOTP.vue:111 msgid "" "The recovery code is only displayed once, please save it in a safe place." msgstr "" @@ -2185,7 +2193,7 @@ msgstr "" msgid "Title" msgstr "" -#: src/views/preference/components/TOTP.vue:90 +#: src/views/preference/components/TOTP.vue:92 msgid "" "To enable it, you need to install the Google or Microsoft Authenticator app " "on your mobile phone." @@ -2207,7 +2215,7 @@ msgstr "" msgid "Too many login failed attempts, please try again later" msgstr "" -#: src/views/preference/components/TOTP.vue:89 +#: src/views/preference/components/TOTP.vue:91 msgid "" "TOTP is a two-factor authentication method that uses a time-based one-time " "password algorithm." diff --git a/app/src/language/es/app.po b/app/src/language/es/app.po index 5f78b876..1205cac4 100644 --- a/app/src/language/es/app.po +++ b/app/src/language/es/app.po @@ -20,7 +20,7 @@ msgstr "" msgid "2FA" msgstr "2FA" -#: src/views/preference/components/TOTP.vue:88 +#: src/views/preference/components/TOTP.vue:90 msgid "2FA Settings" msgstr "Configuración de 2FA" @@ -249,6 +249,10 @@ msgstr "Dir CA" msgid "CADir" msgstr "Directorio CA" +#: src/views/preference/components/TOTP.vue:150 +msgid "Can't scan? Use text key binding" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:252 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:55 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:253 @@ -428,12 +432,12 @@ msgstr "Credencial" msgid "Credentials" msgstr "Credenciales" -#: src/views/preference/components/TOTP.vue:96 +#: src/views/preference/components/TOTP.vue:98 msgid "Current account is enabled 2FA." msgstr "" "La cuenta actual tiene habilitada la autenticación de dos factores (2FA)." -#: src/views/preference/components/TOTP.vue:93 +#: src/views/preference/components/TOTP.vue:95 msgid "Current account is not enabled 2FA." msgstr "" "La cuenta actual no tiene habilitada la autenticación de dos factores (2FA)." @@ -716,11 +720,11 @@ msgstr "Falló el habilitado de %{conf_name} en %{node_name}" msgid "Enable %{conf_name} in %{node_name} successfully" msgstr "Habilitado exitoso de %{conf_name} en %{node_name}" -#: src/views/preference/components/TOTP.vue:122 +#: src/views/preference/components/TOTP.vue:124 msgid "Enable 2FA" msgstr "Habilitar 2FA" -#: src/views/preference/components/TOTP.vue:52 +#: src/views/preference/components/TOTP.vue:54 msgid "Enable 2FA successfully" msgstr "Habilitar 2FA exitoso" @@ -932,7 +936,7 @@ msgstr "" "el máximo de intentos en los minutos del umbral de prohibición, la IP será " "bloqueada por un período de tiempo." -#: src/views/preference/components/TOTP.vue:108 +#: src/views/preference/components/TOTP.vue:110 msgid "" "If you lose your mobile phone, you can use the recovery code to reset your " "2FA." @@ -972,12 +976,12 @@ msgstr "Error de actualización de kernel inicial" msgid "Initialing core upgrader" msgstr "Inicializando la actualización del kernel" -#: src/views/preference/components/TOTP.vue:144 +#: src/views/preference/components/TOTP.vue:157 msgid "Input the code from the app:" msgstr "Ingrese el código de la aplicación:" #: src/components/OTP/OTPAuthorization.vue:49 -#: src/views/preference/components/TOTP.vue:157 +#: src/views/preference/components/TOTP.vue:170 msgid "Input the recovery code:" msgstr "Ingrese el código de recuperación:" @@ -1575,15 +1579,15 @@ msgid "Recovered Successfully" msgstr "Recuperado con éxito" #: src/components/OTP/OTPAuthorization.vue:56 -#: src/views/preference/components/TOTP.vue:164 +#: src/views/preference/components/TOTP.vue:177 msgid "Recovery" msgstr "Recuperación" -#: src/views/preference/components/TOTP.vue:101 +#: src/views/preference/components/TOTP.vue:103 msgid "Recovery Code" msgstr "Código de Recuperación" -#: src/views/preference/components/TOTP.vue:110 +#: src/views/preference/components/TOTP.vue:112 msgid "Recovery Code:" msgstr "Código de Recuperación:" @@ -1710,7 +1714,7 @@ msgstr "Pedido con parámetros incorrectos" msgid "Reset" msgstr "Limpiar" -#: src/views/preference/components/TOTP.vue:130 +#: src/views/preference/components/TOTP.vue:132 msgid "Reset 2FA" msgstr "Restablecer 2FA" @@ -1761,7 +1765,7 @@ msgstr "Guardado con éxito" msgid "Saved successfully" msgstr "Guardado con éxito" -#: src/views/preference/components/TOTP.vue:91 +#: src/views/preference/components/TOTP.vue:93 msgid "Scan the QR code with your mobile phone to add the account to the app." msgstr "" "Escanee el código QR con su teléfono móvil para agregar la cuenta a la " @@ -1771,6 +1775,10 @@ msgstr "" msgid "SDK" msgstr "SDK" +#: src/views/preference/components/TOTP.vue:149 +msgid "Secret has been copied" +msgstr "" + #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:155 msgid "Selector" msgstr "Seleccionador" @@ -1793,8 +1801,8 @@ msgstr "Enviado" #: src/views/environment/BatchUpgrader.vue:57 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68 #: src/views/preference/AuthSettings.vue:49 -#: src/views/preference/components/TOTP.vue:42 -#: src/views/preference/components/TOTP.vue:55 +#: src/views/preference/components/TOTP.vue:44 +#: src/views/preference/components/TOTP.vue:57 #: src/views/preference/Preference.vue:83 src/views/stream/StreamList.vue:113 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42 msgid "Server error" @@ -2037,7 +2045,7 @@ msgstr "La ruta existe, pero el archivo no es un certificado" msgid "The path exists, but the file is not a private key" msgstr "La ruta existe, pero el archivo no es una clave privada" -#: src/views/preference/components/TOTP.vue:109 +#: src/views/preference/components/TOTP.vue:111 msgid "" "The recovery code is only displayed once, please save it in a safe place." msgstr "" @@ -2118,7 +2126,7 @@ msgstr "Consejos" msgid "Title" msgstr "Título" -#: src/views/preference/components/TOTP.vue:90 +#: src/views/preference/components/TOTP.vue:92 msgid "" "To enable it, you need to install the Google or Microsoft Authenticator app " "on your mobile phone." @@ -2148,7 +2156,7 @@ msgstr "" "Demasiados intentos fallidos de inicio de sesión, por favor intente " "nuevamente más tarde" -#: src/views/preference/components/TOTP.vue:89 +#: src/views/preference/components/TOTP.vue:91 msgid "" "TOTP is a two-factor authentication method that uses a time-based one-time " "password algorithm." diff --git a/app/src/language/fr_FR/app.po b/app/src/language/fr_FR/app.po index 80aab6ef..144b5737 100644 --- a/app/src/language/fr_FR/app.po +++ b/app/src/language/fr_FR/app.po @@ -15,7 +15,7 @@ msgstr "" msgid "2FA" msgstr "" -#: src/views/preference/components/TOTP.vue:88 +#: src/views/preference/components/TOTP.vue:90 msgid "2FA Settings" msgstr "" @@ -261,6 +261,10 @@ msgstr "" msgid "CADir" msgstr "" +#: src/views/preference/components/TOTP.vue:150 +msgid "Can't scan? Use text key binding" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:252 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:55 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:253 @@ -452,11 +456,11 @@ msgstr "Identifiant" msgid "Credentials" msgstr "Identifiants" -#: src/views/preference/components/TOTP.vue:96 +#: src/views/preference/components/TOTP.vue:98 msgid "Current account is enabled 2FA." msgstr "" -#: src/views/preference/components/TOTP.vue:93 +#: src/views/preference/components/TOTP.vue:95 msgid "Current account is not enabled 2FA." msgstr "" @@ -753,12 +757,12 @@ msgstr "" msgid "Enable %{conf_name} in %{node_name} successfully" msgstr "" -#: src/views/preference/components/TOTP.vue:122 +#: src/views/preference/components/TOTP.vue:124 #, fuzzy msgid "Enable 2FA" msgstr "Activé" -#: src/views/preference/components/TOTP.vue:52 +#: src/views/preference/components/TOTP.vue:54 #, fuzzy msgid "Enable 2FA successfully" msgstr "Activé avec succès" @@ -977,7 +981,7 @@ msgid "" "ban threshold minutes, the ip will be banned for a period of time." msgstr "" -#: src/views/preference/components/TOTP.vue:108 +#: src/views/preference/components/TOTP.vue:110 msgid "" "If you lose your mobile phone, you can use the recovery code to reset your " "2FA." @@ -1016,12 +1020,12 @@ msgstr "Erreur du programme de mise à niveau initial du core" msgid "Initialing core upgrader" msgstr "Initialisation du programme de mise à niveau du core" -#: src/views/preference/components/TOTP.vue:144 +#: src/views/preference/components/TOTP.vue:157 msgid "Input the code from the app:" msgstr "" #: src/components/OTP/OTPAuthorization.vue:49 -#: src/views/preference/components/TOTP.vue:157 +#: src/views/preference/components/TOTP.vue:170 msgid "Input the recovery code:" msgstr "" @@ -1637,15 +1641,15 @@ msgid "Recovered Successfully" msgstr "Enregistré avec succès" #: src/components/OTP/OTPAuthorization.vue:56 -#: src/views/preference/components/TOTP.vue:164 +#: src/views/preference/components/TOTP.vue:177 msgid "Recovery" msgstr "" -#: src/views/preference/components/TOTP.vue:101 +#: src/views/preference/components/TOTP.vue:103 msgid "Recovery Code" msgstr "" -#: src/views/preference/components/TOTP.vue:110 +#: src/views/preference/components/TOTP.vue:112 msgid "Recovery Code:" msgstr "" @@ -1786,7 +1790,7 @@ msgstr "" msgid "Reset" msgstr "Réinitialiser" -#: src/views/preference/components/TOTP.vue:130 +#: src/views/preference/components/TOTP.vue:132 #, fuzzy msgid "Reset 2FA" msgstr "Réinitialiser" @@ -1838,7 +1842,7 @@ msgstr "Sauvegarde réussie" msgid "Saved successfully" msgstr "Enregistré avec succès" -#: src/views/preference/components/TOTP.vue:91 +#: src/views/preference/components/TOTP.vue:93 msgid "Scan the QR code with your mobile phone to add the account to the app." msgstr "" @@ -1846,6 +1850,10 @@ msgstr "" msgid "SDK" msgstr "" +#: src/views/preference/components/TOTP.vue:149 +msgid "Secret has been copied" +msgstr "" + #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:155 msgid "Selector" msgstr "Sélecteur" @@ -1868,8 +1876,8 @@ msgstr "Envoyer" #: src/views/environment/BatchUpgrader.vue:57 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68 #: src/views/preference/AuthSettings.vue:49 -#: src/views/preference/components/TOTP.vue:42 -#: src/views/preference/components/TOTP.vue:55 +#: src/views/preference/components/TOTP.vue:44 +#: src/views/preference/components/TOTP.vue:57 #: src/views/preference/Preference.vue:83 src/views/stream/StreamList.vue:113 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42 msgid "Server error" @@ -2118,7 +2126,7 @@ msgstr "Chemin de la clé du certificat SSL" msgid "The path exists, but the file is not a private key" msgstr "" -#: src/views/preference/components/TOTP.vue:109 +#: src/views/preference/components/TOTP.vue:111 msgid "" "The recovery code is only displayed once, please save it in a safe place." msgstr "" @@ -2195,7 +2203,7 @@ msgstr "" msgid "Title" msgstr "" -#: src/views/preference/components/TOTP.vue:90 +#: src/views/preference/components/TOTP.vue:92 msgid "" "To enable it, you need to install the Google or Microsoft Authenticator app " "on your mobile phone." @@ -2221,7 +2229,7 @@ msgstr "" msgid "Too many login failed attempts, please try again later" msgstr "" -#: src/views/preference/components/TOTP.vue:89 +#: src/views/preference/components/TOTP.vue:91 msgid "" "TOTP is a two-factor authentication method that uses a time-based one-time " "password algorithm." diff --git a/app/src/language/ko_KR/app.po b/app/src/language/ko_KR/app.po index 80123c55..79a88549 100644 --- a/app/src/language/ko_KR/app.po +++ b/app/src/language/ko_KR/app.po @@ -18,7 +18,7 @@ msgstr "" msgid "2FA" msgstr "2FA" -#: src/views/preference/components/TOTP.vue:88 +#: src/views/preference/components/TOTP.vue:90 msgid "2FA Settings" msgstr "2FA 설정" @@ -247,6 +247,10 @@ msgstr "CA 디렉토리" msgid "CADir" msgstr "CA 디렉토리" +#: src/views/preference/components/TOTP.vue:150 +msgid "Can't scan? Use text key binding" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:252 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:55 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:253 @@ -431,11 +435,11 @@ msgstr "인증 정보" msgid "Credentials" msgstr "인증 정보들" -#: src/views/preference/components/TOTP.vue:96 +#: src/views/preference/components/TOTP.vue:98 msgid "Current account is enabled 2FA." msgstr "" -#: src/views/preference/components/TOTP.vue:93 +#: src/views/preference/components/TOTP.vue:95 msgid "Current account is not enabled 2FA." msgstr "" @@ -716,12 +720,12 @@ msgstr "%{node_name}에서 %{conf_name} 활성화 실패" msgid "Enable %{conf_name} in %{node_name} successfully" msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨" -#: src/views/preference/components/TOTP.vue:122 +#: src/views/preference/components/TOTP.vue:124 #, fuzzy msgid "Enable 2FA" msgstr "활성화" -#: src/views/preference/components/TOTP.vue:52 +#: src/views/preference/components/TOTP.vue:54 #, fuzzy msgid "Enable 2FA successfully" msgstr "성공적으로 활성화" @@ -938,7 +942,7 @@ msgid "" "ban threshold minutes, the ip will be banned for a period of time." msgstr "" -#: src/views/preference/components/TOTP.vue:108 +#: src/views/preference/components/TOTP.vue:110 msgid "" "If you lose your mobile phone, you can use the recovery code to reset your " "2FA." @@ -976,12 +980,12 @@ msgstr "초기 코어 업그레이더 오류" msgid "Initialing core upgrader" msgstr "코어 업그레이더 초기화" -#: src/views/preference/components/TOTP.vue:144 +#: src/views/preference/components/TOTP.vue:157 msgid "Input the code from the app:" msgstr "" #: src/components/OTP/OTPAuthorization.vue:49 -#: src/views/preference/components/TOTP.vue:157 +#: src/views/preference/components/TOTP.vue:170 msgid "Input the recovery code:" msgstr "" @@ -1601,15 +1605,15 @@ msgid "Recovered Successfully" msgstr "성공적으로 제거됨" #: src/components/OTP/OTPAuthorization.vue:56 -#: src/views/preference/components/TOTP.vue:164 +#: src/views/preference/components/TOTP.vue:177 msgid "Recovery" msgstr "" -#: src/views/preference/components/TOTP.vue:101 +#: src/views/preference/components/TOTP.vue:103 msgid "Recovery Code" msgstr "" -#: src/views/preference/components/TOTP.vue:110 +#: src/views/preference/components/TOTP.vue:112 msgid "Recovery Code:" msgstr "" @@ -1751,7 +1755,7 @@ msgstr "잘못된 매개변수로 요청됨" msgid "Reset" msgstr "재설정" -#: src/views/preference/components/TOTP.vue:130 +#: src/views/preference/components/TOTP.vue:132 #, fuzzy msgid "Reset 2FA" msgstr "재설정" @@ -1805,7 +1809,7 @@ msgstr "성공적으로 저장됨" msgid "Saved successfully" msgstr "성공적으로 저장됨" -#: src/views/preference/components/TOTP.vue:91 +#: src/views/preference/components/TOTP.vue:93 msgid "Scan the QR code with your mobile phone to add the account to the app." msgstr "" @@ -1813,6 +1817,10 @@ msgstr "" msgid "SDK" msgstr "" +#: src/views/preference/components/TOTP.vue:149 +msgid "Secret has been copied" +msgstr "" + #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:155 msgid "Selector" msgstr "선택" @@ -1835,8 +1843,8 @@ msgstr "보내기" #: src/views/environment/BatchUpgrader.vue:57 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68 #: src/views/preference/AuthSettings.vue:49 -#: src/views/preference/components/TOTP.vue:42 -#: src/views/preference/components/TOTP.vue:55 +#: src/views/preference/components/TOTP.vue:44 +#: src/views/preference/components/TOTP.vue:57 #: src/views/preference/Preference.vue:83 src/views/stream/StreamList.vue:113 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42 msgid "Server error" @@ -2084,7 +2092,7 @@ msgstr "Certificate Status" msgid "The path exists, but the file is not a private key" msgstr "경로는 존재하지만 파일은 개인 키가 아닙니다" -#: src/views/preference/components/TOTP.vue:109 +#: src/views/preference/components/TOTP.vue:111 msgid "" "The recovery code is only displayed once, please save it in a safe place." msgstr "" @@ -2159,7 +2167,7 @@ msgstr "팁" msgid "Title" msgstr "제목" -#: src/views/preference/components/TOTP.vue:90 +#: src/views/preference/components/TOTP.vue:92 msgid "" "To enable it, you need to install the Google or Microsoft Authenticator app " "on your mobile phone." @@ -2184,7 +2192,7 @@ msgstr "토큰이 유효하지 않습니다" msgid "Too many login failed attempts, please try again later" msgstr "" -#: src/views/preference/components/TOTP.vue:89 +#: src/views/preference/components/TOTP.vue:91 msgid "" "TOTP is a two-factor authentication method that uses a time-based one-time " "password algorithm." diff --git a/app/src/language/messages.pot b/app/src/language/messages.pot index 69efc165..843807be 100644 --- a/app/src/language/messages.pot +++ b/app/src/language/messages.pot @@ -6,7 +6,7 @@ msgstr "" msgid "2FA" msgstr "" -#: src/views/preference/components/TOTP.vue:88 +#: src/views/preference/components/TOTP.vue:90 msgid "2FA Settings" msgstr "" @@ -247,6 +247,10 @@ msgstr "" msgid "CADir" msgstr "" +#: src/views/preference/components/TOTP.vue:150 +msgid "Can't scan? Use text key binding" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:252 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:55 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:253 @@ -428,11 +432,11 @@ msgstr "" msgid "Credentials" msgstr "" -#: src/views/preference/components/TOTP.vue:96 +#: src/views/preference/components/TOTP.vue:98 msgid "Current account is enabled 2FA." msgstr "" -#: src/views/preference/components/TOTP.vue:93 +#: src/views/preference/components/TOTP.vue:95 msgid "Current account is not enabled 2FA." msgstr "" @@ -718,11 +722,11 @@ msgstr "" msgid "Enable %{conf_name} in %{node_name} successfully" msgstr "" -#: src/views/preference/components/TOTP.vue:122 +#: src/views/preference/components/TOTP.vue:124 msgid "Enable 2FA" msgstr "" -#: src/views/preference/components/TOTP.vue:52 +#: src/views/preference/components/TOTP.vue:54 msgid "Enable 2FA successfully" msgstr "" @@ -937,7 +941,7 @@ msgstr "" msgid "If the number of login failed attempts from a ip reach the max attempts in ban threshold minutes, the ip will be banned for a period of time." msgstr "" -#: src/views/preference/components/TOTP.vue:108 +#: src/views/preference/components/TOTP.vue:110 msgid "If you lose your mobile phone, you can use the recovery code to reset your 2FA." msgstr "" @@ -971,12 +975,12 @@ msgstr "" msgid "Initialing core upgrader" msgstr "" -#: src/views/preference/components/TOTP.vue:144 +#: src/views/preference/components/TOTP.vue:157 msgid "Input the code from the app:" msgstr "" #: src/components/OTP/OTPAuthorization.vue:49 -#: src/views/preference/components/TOTP.vue:157 +#: src/views/preference/components/TOTP.vue:170 msgid "Input the recovery code:" msgstr "" @@ -1556,15 +1560,15 @@ msgid "Recovered Successfully" msgstr "" #: src/components/OTP/OTPAuthorization.vue:56 -#: src/views/preference/components/TOTP.vue:164 +#: src/views/preference/components/TOTP.vue:177 msgid "Recovery" msgstr "" -#: src/views/preference/components/TOTP.vue:101 +#: src/views/preference/components/TOTP.vue:103 msgid "Recovery Code" msgstr "" -#: src/views/preference/components/TOTP.vue:110 +#: src/views/preference/components/TOTP.vue:112 msgid "Recovery Code:" msgstr "" @@ -1685,7 +1689,7 @@ msgstr "" msgid "Reset" msgstr "" -#: src/views/preference/components/TOTP.vue:130 +#: src/views/preference/components/TOTP.vue:132 msgid "Reset 2FA" msgstr "" @@ -1740,7 +1744,7 @@ msgstr "" msgid "Saved successfully" msgstr "" -#: src/views/preference/components/TOTP.vue:91 +#: src/views/preference/components/TOTP.vue:93 msgid "Scan the QR code with your mobile phone to add the account to the app." msgstr "" @@ -1748,6 +1752,10 @@ msgstr "" msgid "SDK" msgstr "" +#: src/views/preference/components/TOTP.vue:149 +msgid "Secret has been copied" +msgstr "" + #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:155 msgid "Selector" msgstr "" @@ -1772,8 +1780,8 @@ msgstr "" #: src/views/environment/Environment.vue:15 #: src/views/other/Install.vue:68 #: src/views/preference/AuthSettings.vue:49 -#: src/views/preference/components/TOTP.vue:42 -#: src/views/preference/components/TOTP.vue:55 +#: src/views/preference/components/TOTP.vue:44 +#: src/views/preference/components/TOTP.vue:57 #: src/views/preference/Preference.vue:83 #: src/views/stream/StreamList.vue:113 #: src/views/stream/StreamList.vue:81 @@ -1993,7 +2001,7 @@ msgstr "" msgid "The path exists, but the file is not a private key" msgstr "" -#: src/views/preference/components/TOTP.vue:109 +#: src/views/preference/components/TOTP.vue:111 msgid "The recovery code is only displayed once, please save it in a safe place." msgstr "" @@ -2054,7 +2062,7 @@ msgstr "" msgid "Title" msgstr "" -#: src/views/preference/components/TOTP.vue:90 +#: src/views/preference/components/TOTP.vue:92 msgid "To enable it, you need to install the Google or Microsoft Authenticator app on your mobile phone." msgstr "" @@ -2070,7 +2078,7 @@ msgstr "" msgid "Too many login failed attempts, please try again later" msgstr "" -#: src/views/preference/components/TOTP.vue:89 +#: src/views/preference/components/TOTP.vue:91 msgid "TOTP is a two-factor authentication method that uses a time-based one-time password algorithm." msgstr "" diff --git a/app/src/language/ru_RU/app.po b/app/src/language/ru_RU/app.po index 2f10b31c..9baa2a58 100644 --- a/app/src/language/ru_RU/app.po +++ b/app/src/language/ru_RU/app.po @@ -18,7 +18,7 @@ msgstr "" msgid "2FA" msgstr "2ФА" -#: src/views/preference/components/TOTP.vue:88 +#: src/views/preference/components/TOTP.vue:90 msgid "2FA Settings" msgstr "Настройки 2ФА" @@ -250,6 +250,10 @@ msgstr "Директория корневого сертификата" msgid "CADir" msgstr "" +#: src/views/preference/components/TOTP.vue:150 +msgid "Can't scan? Use text key binding" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:252 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:55 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:253 @@ -429,11 +433,11 @@ msgstr "Учетные данные" msgid "Credentials" msgstr "Учетные данные" -#: src/views/preference/components/TOTP.vue:96 +#: src/views/preference/components/TOTP.vue:98 msgid "Current account is enabled 2FA." msgstr "Текущая учетная запись имеет включенную 2ФА." -#: src/views/preference/components/TOTP.vue:93 +#: src/views/preference/components/TOTP.vue:95 msgid "Current account is not enabled 2FA." msgstr "" "Текущая учетная запись не имеет включенной двухфакторной аутентификации." @@ -716,11 +720,11 @@ msgstr "Включение %{conf_name} in %{node_name} нипалучилася msgid "Enable %{conf_name} in %{node_name} successfully" msgstr "Включение %{conf_name} in %{node_name} успешно" -#: src/views/preference/components/TOTP.vue:122 +#: src/views/preference/components/TOTP.vue:124 msgid "Enable 2FA" msgstr "Включить 2ФА" -#: src/views/preference/components/TOTP.vue:52 +#: src/views/preference/components/TOTP.vue:54 msgid "Enable 2FA successfully" msgstr "Двухфакторная аутентификация успешно включена" @@ -931,7 +935,7 @@ msgstr "" "количества попыток в течение пороговых минут блокировки, IP будет " "заблокирован на определенный период времени." -#: src/views/preference/components/TOTP.vue:108 +#: src/views/preference/components/TOTP.vue:110 msgid "" "If you lose your mobile phone, you can use the recovery code to reset your " "2FA." @@ -971,12 +975,12 @@ msgstr "Ошибка первоначального обновления ядр msgid "Initialing core upgrader" msgstr "Инициализация программы обновления ядра" -#: src/views/preference/components/TOTP.vue:144 +#: src/views/preference/components/TOTP.vue:157 msgid "Input the code from the app:" msgstr "Введите код из приложения:" #: src/components/OTP/OTPAuthorization.vue:49 -#: src/views/preference/components/TOTP.vue:157 +#: src/views/preference/components/TOTP.vue:170 msgid "Input the recovery code:" msgstr "Введите код восстановления:" @@ -1573,15 +1577,15 @@ msgid "Recovered Successfully" msgstr "Восстановлено успешно" #: src/components/OTP/OTPAuthorization.vue:56 -#: src/views/preference/components/TOTP.vue:164 +#: src/views/preference/components/TOTP.vue:177 msgid "Recovery" msgstr "Восстановление" -#: src/views/preference/components/TOTP.vue:101 +#: src/views/preference/components/TOTP.vue:103 msgid "Recovery Code" msgstr "Код восстановления" -#: src/views/preference/components/TOTP.vue:110 +#: src/views/preference/components/TOTP.vue:112 msgid "Recovery Code:" msgstr "Код восстановления:" @@ -1709,7 +1713,7 @@ msgstr "Запрос с неправильными параметрами" msgid "Reset" msgstr "Сброс" -#: src/views/preference/components/TOTP.vue:130 +#: src/views/preference/components/TOTP.vue:132 msgid "Reset 2FA" msgstr "Сброс 2FA" @@ -1760,7 +1764,7 @@ msgstr "Сохранено успешно" msgid "Saved successfully" msgstr "Успешно сохранено" -#: src/views/preference/components/TOTP.vue:91 +#: src/views/preference/components/TOTP.vue:93 msgid "Scan the QR code with your mobile phone to add the account to the app." msgstr "" "Отсканируйте QR-код с помощью мобильного телефона, чтобы добавить учетную " @@ -1770,6 +1774,10 @@ msgstr "" msgid "SDK" msgstr "SDK" +#: src/views/preference/components/TOTP.vue:149 +msgid "Secret has been copied" +msgstr "" + #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:155 msgid "Selector" msgstr "Выбор" @@ -1792,8 +1800,8 @@ msgstr "Отправлено" #: src/views/environment/BatchUpgrader.vue:57 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68 #: src/views/preference/AuthSettings.vue:49 -#: src/views/preference/components/TOTP.vue:42 -#: src/views/preference/components/TOTP.vue:55 +#: src/views/preference/components/TOTP.vue:44 +#: src/views/preference/components/TOTP.vue:57 #: src/views/preference/Preference.vue:83 src/views/stream/StreamList.vue:113 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42 msgid "Server error" @@ -2034,7 +2042,7 @@ msgstr "Путь существует, но файл не является се msgid "The path exists, but the file is not a private key" msgstr "Путь существует, но файл не является приватным ключом" -#: src/views/preference/components/TOTP.vue:109 +#: src/views/preference/components/TOTP.vue:111 msgid "" "The recovery code is only displayed once, please save it in a safe place." msgstr "" @@ -2115,7 +2123,7 @@ msgstr "Советы" msgid "Title" msgstr "Заголовок" -#: src/views/preference/components/TOTP.vue:90 +#: src/views/preference/components/TOTP.vue:92 msgid "" "To enable it, you need to install the Google or Microsoft Authenticator app " "on your mobile phone." @@ -2143,7 +2151,7 @@ msgstr "Токен недействителен" msgid "Too many login failed attempts, please try again later" msgstr "Слишком много неудачных попыток входа, попробуйте позже" -#: src/views/preference/components/TOTP.vue:89 +#: src/views/preference/components/TOTP.vue:91 msgid "" "TOTP is a two-factor authentication method that uses a time-based one-time " "password algorithm." diff --git a/app/src/language/vi_VN/app.po b/app/src/language/vi_VN/app.po index d07aae75..f8b83b52 100644 --- a/app/src/language/vi_VN/app.po +++ b/app/src/language/vi_VN/app.po @@ -13,7 +13,7 @@ msgstr "" msgid "2FA" msgstr "" -#: src/views/preference/components/TOTP.vue:88 +#: src/views/preference/components/TOTP.vue:90 msgid "2FA Settings" msgstr "" @@ -261,6 +261,10 @@ msgstr "" msgid "CADir" msgstr "" +#: src/views/preference/components/TOTP.vue:150 +msgid "Can't scan? Use text key binding" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:252 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:55 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:253 @@ -454,11 +458,11 @@ msgstr "Chứng chỉ" msgid "Credentials" msgstr "Chứng chỉ" -#: src/views/preference/components/TOTP.vue:96 +#: src/views/preference/components/TOTP.vue:98 msgid "Current account is enabled 2FA." msgstr "" -#: src/views/preference/components/TOTP.vue:93 +#: src/views/preference/components/TOTP.vue:95 msgid "Current account is not enabled 2FA." msgstr "" @@ -758,12 +762,12 @@ msgstr "Không thể bật %{conf_name} trên %{node_name}" msgid "Enable %{conf_name} in %{node_name} successfully" msgstr "Đã bật %{conf_name} trên %{node_name}" -#: src/views/preference/components/TOTP.vue:122 +#: src/views/preference/components/TOTP.vue:124 #, fuzzy msgid "Enable 2FA" msgstr "Đã bật" -#: src/views/preference/components/TOTP.vue:52 +#: src/views/preference/components/TOTP.vue:54 #, fuzzy msgid "Enable 2FA successfully" msgstr "Đã bật" @@ -983,7 +987,7 @@ msgid "" "ban threshold minutes, the ip will be banned for a period of time." msgstr "" -#: src/views/preference/components/TOTP.vue:108 +#: src/views/preference/components/TOTP.vue:110 msgid "" "If you lose your mobile phone, you can use the recovery code to reset your " "2FA." @@ -1022,12 +1026,12 @@ msgstr "Không thể khởi tạo trình nâng cấp" msgid "Initialing core upgrader" msgstr "Đang khởi tạo trình nâng cấp" -#: src/views/preference/components/TOTP.vue:144 +#: src/views/preference/components/TOTP.vue:157 msgid "Input the code from the app:" msgstr "" #: src/components/OTP/OTPAuthorization.vue:49 -#: src/views/preference/components/TOTP.vue:157 +#: src/views/preference/components/TOTP.vue:170 msgid "Input the recovery code:" msgstr "" @@ -1644,15 +1648,15 @@ msgid "Recovered Successfully" msgstr "Xoá thành công" #: src/components/OTP/OTPAuthorization.vue:56 -#: src/views/preference/components/TOTP.vue:164 +#: src/views/preference/components/TOTP.vue:177 msgid "Recovery" msgstr "" -#: src/views/preference/components/TOTP.vue:101 +#: src/views/preference/components/TOTP.vue:103 msgid "Recovery Code" msgstr "" -#: src/views/preference/components/TOTP.vue:110 +#: src/views/preference/components/TOTP.vue:112 msgid "Recovery Code:" msgstr "" @@ -1794,7 +1798,7 @@ msgstr "Yêu cầu có chứa tham số sai" msgid "Reset" msgstr "Đặt lại" -#: src/views/preference/components/TOTP.vue:130 +#: src/views/preference/components/TOTP.vue:132 #, fuzzy msgid "Reset 2FA" msgstr "Đặt lại" @@ -1848,7 +1852,7 @@ msgstr "Lưu thành công" msgid "Saved successfully" msgstr "Lưu thành công" -#: src/views/preference/components/TOTP.vue:91 +#: src/views/preference/components/TOTP.vue:93 msgid "Scan the QR code with your mobile phone to add the account to the app." msgstr "" @@ -1856,6 +1860,10 @@ msgstr "" msgid "SDK" msgstr "" +#: src/views/preference/components/TOTP.vue:149 +msgid "Secret has been copied" +msgstr "" + #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:155 msgid "Selector" msgstr "Bộ chọn" @@ -1878,8 +1886,8 @@ msgstr "Gửi" #: src/views/environment/BatchUpgrader.vue:57 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68 #: src/views/preference/AuthSettings.vue:49 -#: src/views/preference/components/TOTP.vue:42 -#: src/views/preference/components/TOTP.vue:55 +#: src/views/preference/components/TOTP.vue:44 +#: src/views/preference/components/TOTP.vue:57 #: src/views/preference/Preference.vue:83 src/views/stream/StreamList.vue:113 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42 msgid "Server error" @@ -2122,7 +2130,7 @@ msgstr "" msgid "The path exists, but the file is not a private key" msgstr "" -#: src/views/preference/components/TOTP.vue:109 +#: src/views/preference/components/TOTP.vue:111 msgid "" "The recovery code is only displayed once, please save it in a safe place." msgstr "" @@ -2194,7 +2202,7 @@ msgstr "" msgid "Title" msgstr "Tiêu đề" -#: src/views/preference/components/TOTP.vue:90 +#: src/views/preference/components/TOTP.vue:92 msgid "" "To enable it, you need to install the Google or Microsoft Authenticator app " "on your mobile phone." @@ -2220,7 +2228,7 @@ msgstr "" msgid "Too many login failed attempts, please try again later" msgstr "" -#: src/views/preference/components/TOTP.vue:89 +#: src/views/preference/components/TOTP.vue:91 msgid "" "TOTP is a two-factor authentication method that uses a time-based one-time " "password algorithm." diff --git a/app/src/language/zh_CN/app.mo b/app/src/language/zh_CN/app.mo index e4908debac439579287188285b74b784d1db00ec..063f5875b349003bf96fb2612f61f1cf12ef8103 100644 GIT binary patch delta 10435 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 diff --git a/app/src/language/zh_CN/app.po b/app/src/language/zh_CN/app.po index d620f6b5..fc75712a 100644 --- a/app/src/language/zh_CN/app.po +++ b/app/src/language/zh_CN/app.po @@ -17,7 +17,7 @@ msgstr "" msgid "2FA" msgstr "2FA" -#: src/views/preference/components/TOTP.vue:88 +#: src/views/preference/components/TOTP.vue:90 msgid "2FA Settings" msgstr "2FA 设置" @@ -246,6 +246,10 @@ msgstr "CA Dir" msgid "CADir" msgstr "CADir" +#: src/views/preference/components/TOTP.vue:150 +msgid "Can't scan? Use text key binding" +msgstr "无法扫描?使用文本密钥绑定" + #: src/components/ChatGPT/ChatGPT.vue:252 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:55 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:253 @@ -423,11 +427,11 @@ msgstr "DNS 凭证" msgid "Credentials" msgstr "凭证" -#: src/views/preference/components/TOTP.vue:96 +#: src/views/preference/components/TOTP.vue:98 msgid "Current account is enabled 2FA." msgstr "当前账户已启用二步验证。" -#: src/views/preference/components/TOTP.vue:93 +#: src/views/preference/components/TOTP.vue:95 msgid "Current account is not enabled 2FA." msgstr "当前用户未启用二步验证。" @@ -704,11 +708,11 @@ msgstr "在%{node_name}中启用%{conf_name}失败" msgid "Enable %{conf_name} in %{node_name} successfully" msgstr "成功启用%{node_name}中的%{conf_name}" -#: src/views/preference/components/TOTP.vue:122 +#: src/views/preference/components/TOTP.vue:124 msgid "Enable 2FA" msgstr "启用二步验证" -#: src/views/preference/components/TOTP.vue:52 +#: src/views/preference/components/TOTP.vue:54 msgid "Enable 2FA successfully" msgstr "二步验证启用成功" @@ -918,7 +922,7 @@ msgstr "" "如果某个 IP 的登录失败次数达到禁用阈值分钟内的最大尝试次数,该 IP 将被禁止登" "录一段时间。" -#: src/views/preference/components/TOTP.vue:108 +#: src/views/preference/components/TOTP.vue:110 msgid "" "If you lose your mobile phone, you can use the recovery code to reset your " "2FA." @@ -954,12 +958,12 @@ msgstr "初始化核心升级程序错误" msgid "Initialing core upgrader" msgstr "初始化核心升级器" -#: src/views/preference/components/TOTP.vue:144 +#: src/views/preference/components/TOTP.vue:157 msgid "Input the code from the app:" msgstr "输入应用程序中的代码:" #: src/components/OTP/OTPAuthorization.vue:49 -#: src/views/preference/components/TOTP.vue:157 +#: src/views/preference/components/TOTP.vue:170 msgid "Input the recovery code:" msgstr "输入恢复代码:" @@ -1545,15 +1549,15 @@ msgid "Recovered Successfully" msgstr "恢复成功" #: src/components/OTP/OTPAuthorization.vue:56 -#: src/views/preference/components/TOTP.vue:164 +#: src/views/preference/components/TOTP.vue:177 msgid "Recovery" msgstr "恢复" -#: src/views/preference/components/TOTP.vue:101 +#: src/views/preference/components/TOTP.vue:103 msgid "Recovery Code" msgstr "恢复代码" -#: src/views/preference/components/TOTP.vue:110 +#: src/views/preference/components/TOTP.vue:112 msgid "Recovery Code:" msgstr "恢复代码:" @@ -1680,7 +1684,7 @@ msgstr "请求参数错误" msgid "Reset" msgstr "重置" -#: src/views/preference/components/TOTP.vue:130 +#: src/views/preference/components/TOTP.vue:132 msgid "Reset 2FA" msgstr "重置二步验证" @@ -1731,7 +1735,7 @@ msgstr "保存成功" msgid "Saved successfully" msgstr "保存成功" -#: src/views/preference/components/TOTP.vue:91 +#: src/views/preference/components/TOTP.vue:93 msgid "Scan the QR code with your mobile phone to add the account to the app." msgstr "用手机扫描二维码,将账户添加到应用程序中。" @@ -1739,6 +1743,10 @@ msgstr "用手机扫描二维码,将账户添加到应用程序中。" msgid "SDK" msgstr "SDK" +#: src/views/preference/components/TOTP.vue:149 +msgid "Secret has been copied" +msgstr "密钥已复制" + #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:155 msgid "Selector" msgstr "选择器" @@ -1761,8 +1769,8 @@ msgstr "上传" #: src/views/environment/BatchUpgrader.vue:57 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68 #: src/views/preference/AuthSettings.vue:49 -#: src/views/preference/components/TOTP.vue:42 -#: src/views/preference/components/TOTP.vue:55 +#: src/views/preference/components/TOTP.vue:44 +#: src/views/preference/components/TOTP.vue:57 #: src/views/preference/Preference.vue:83 src/views/stream/StreamList.vue:113 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42 msgid "Server error" @@ -1992,7 +2000,7 @@ msgstr "路径存在,但文件不是证书" msgid "The path exists, but the file is not a private key" msgstr "路径存在,但文件不是私钥" -#: src/views/preference/components/TOTP.vue:109 +#: src/views/preference/components/TOTP.vue:111 msgid "" "The recovery code is only displayed once, please save it in a safe place." msgstr "恢复密码只会显示一次,请妥善保存。" @@ -2064,7 +2072,7 @@ msgstr "提示" msgid "Title" msgstr "标题" -#: src/views/preference/components/TOTP.vue:90 +#: src/views/preference/components/TOTP.vue:92 msgid "" "To enable it, you need to install the Google or Microsoft Authenticator app " "on your mobile phone." @@ -2089,7 +2097,7 @@ msgstr "Token 无效" msgid "Too many login failed attempts, please try again later" msgstr "登录失败次数过多,请稍后再试" -#: src/views/preference/components/TOTP.vue:89 +#: src/views/preference/components/TOTP.vue:91 msgid "" "TOTP is a two-factor authentication method that uses a time-based one-time " "password algorithm." diff --git a/app/src/language/zh_TW/app.po b/app/src/language/zh_TW/app.po index d84041fa..e81844cd 100644 --- a/app/src/language/zh_TW/app.po +++ b/app/src/language/zh_TW/app.po @@ -21,7 +21,7 @@ msgstr "" msgid "2FA" msgstr "多重要素驗證" -#: src/views/preference/components/TOTP.vue:88 +#: src/views/preference/components/TOTP.vue:90 msgid "2FA Settings" msgstr "多重要素驗證設定" @@ -250,6 +250,10 @@ msgstr "CA Dir" msgid "CADir" msgstr "CADir" +#: src/views/preference/components/TOTP.vue:150 +msgid "Can't scan? Use text key binding" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:252 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:55 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:253 @@ -427,11 +431,11 @@ msgstr "認證" msgid "Credentials" msgstr "認證資訊" -#: src/views/preference/components/TOTP.vue:96 +#: src/views/preference/components/TOTP.vue:98 msgid "Current account is enabled 2FA." msgstr "當前帳戶已啟用多因素身份驗證。" -#: src/views/preference/components/TOTP.vue:93 +#: src/views/preference/components/TOTP.vue:95 msgid "Current account is not enabled 2FA." msgstr "當前帳戶未啟用多因素身份驗證。" @@ -708,11 +712,11 @@ msgstr "在 %{node_name} 啟用 %{conf_name} 失敗" msgid "Enable %{conf_name} in %{node_name} successfully" msgstr "成功在 %{node_name} 啟用 %{conf_name}" -#: src/views/preference/components/TOTP.vue:122 +#: src/views/preference/components/TOTP.vue:124 msgid "Enable 2FA" msgstr "啟用多因素身份驗證" -#: src/views/preference/components/TOTP.vue:52 +#: src/views/preference/components/TOTP.vue:54 msgid "Enable 2FA successfully" msgstr "啟用多因素身份驗證成功" @@ -922,7 +926,7 @@ msgstr "" "如果來自某個 IP 的登錄失敗次數在禁止閾值分鐘內達到最大嘗試次數,該 IP 將被禁" "止一段時間。" -#: src/views/preference/components/TOTP.vue:108 +#: src/views/preference/components/TOTP.vue:110 msgid "" "If you lose your mobile phone, you can use the recovery code to reset your " "2FA." @@ -958,12 +962,12 @@ msgstr "初始化核心升級程式錯誤" msgid "Initialing core upgrader" msgstr "正在初始化核心升級程式" -#: src/views/preference/components/TOTP.vue:144 +#: src/views/preference/components/TOTP.vue:157 msgid "Input the code from the app:" msgstr "請輸入應用程式中的代碼:" #: src/components/OTP/OTPAuthorization.vue:49 -#: src/views/preference/components/TOTP.vue:157 +#: src/views/preference/components/TOTP.vue:170 msgid "Input the recovery code:" msgstr "輸入恢復碼:" @@ -1548,15 +1552,15 @@ msgid "Recovered Successfully" msgstr "恢復成功" #: src/components/OTP/OTPAuthorization.vue:56 -#: src/views/preference/components/TOTP.vue:164 +#: src/views/preference/components/TOTP.vue:177 msgid "Recovery" msgstr "恢復" -#: src/views/preference/components/TOTP.vue:101 +#: src/views/preference/components/TOTP.vue:103 msgid "Recovery Code" msgstr "恢復碼" -#: src/views/preference/components/TOTP.vue:110 +#: src/views/preference/components/TOTP.vue:112 msgid "Recovery Code:" msgstr "恢復碼:" @@ -1683,7 +1687,7 @@ msgstr "請求參數錯誤" msgid "Reset" msgstr "重設" -#: src/views/preference/components/TOTP.vue:130 +#: src/views/preference/components/TOTP.vue:132 msgid "Reset 2FA" msgstr "重置多重因素驗證" @@ -1734,7 +1738,7 @@ msgstr "儲存成功" msgid "Saved successfully" msgstr "儲存成功" -#: src/views/preference/components/TOTP.vue:91 +#: src/views/preference/components/TOTP.vue:93 msgid "Scan the QR code with your mobile phone to add the account to the app." msgstr "用手機掃描二維碼將賬戶添加到應用程序中。" @@ -1742,6 +1746,10 @@ msgstr "用手機掃描二維碼將賬戶添加到應用程序中。" msgid "SDK" msgstr "SDK" +#: src/views/preference/components/TOTP.vue:149 +msgid "Secret has been copied" +msgstr "" + #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:155 msgid "Selector" msgstr "選擇器" @@ -1764,8 +1772,8 @@ msgstr "傳送" #: src/views/environment/BatchUpgrader.vue:57 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68 #: src/views/preference/AuthSettings.vue:49 -#: src/views/preference/components/TOTP.vue:42 -#: src/views/preference/components/TOTP.vue:55 +#: src/views/preference/components/TOTP.vue:44 +#: src/views/preference/components/TOTP.vue:57 #: src/views/preference/Preference.vue:83 src/views/stream/StreamList.vue:113 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42 msgid "Server error" @@ -1995,7 +2003,7 @@ msgstr "路徑存在,但檔案不是憑證" msgid "The path exists, but the file is not a private key" msgstr "路徑存在,但檔案不是金鑰" -#: src/views/preference/components/TOTP.vue:109 +#: src/views/preference/components/TOTP.vue:111 msgid "" "The recovery code is only displayed once, please save it in a safe place." msgstr "恢復碼僅顯示一次,請將其保存在安全的地方。" @@ -2067,7 +2075,7 @@ msgstr "提示" msgid "Title" msgstr "標題" -#: src/views/preference/components/TOTP.vue:90 +#: src/views/preference/components/TOTP.vue:92 msgid "" "To enable it, you need to install the Google or Microsoft Authenticator app " "on your mobile phone." @@ -2092,7 +2100,7 @@ msgstr "令牌無效" msgid "Too many login failed attempts, please try again later" msgstr "登錄失敗次數過多,請稍後再試" -#: src/views/preference/components/TOTP.vue:89 +#: src/views/preference/components/TOTP.vue:91 msgid "" "TOTP is a two-factor authentication method that uses a time-based one-time " "password algorithm." diff --git a/app/src/views/preference/components/TOTP.vue b/app/src/views/preference/components/TOTP.vue index 7be2c3b3..6c65f245 100644 --- a/app/src/views/preference/components/TOTP.vue +++ b/app/src/views/preference/components/TOTP.vue @@ -1,8 +1,10 @@