Browse Source

chore: update translations

Jacky 1 year ago
parent
commit
802d05f692

+ 1 - 1
app/src/language/LINGUAS

@@ -1 +1 @@
-es fr_FR ko_KR ru_RU vi_VN zh_CN zh_TW
+en zh_CN zh_TW fr_FR es ru_RU vi_VN ko_KR

+ 120 - 33
app/src/language/en/app.po

@@ -9,7 +9,11 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/routes/index.ts:256
+#: src/views/preference/components/TOTP.vue:88
+msgid "2FA Settings"
+msgstr ""
+
+#: src/routes/index.ts:261
 msgid "About"
 msgstr "About"
 
@@ -28,7 +32,7 @@ msgstr "Username"
 #: src/views/certificate/DNSCredential.vue:33 src/views/config/config.ts:34
 #: src/views/domain/DomainList.vue:47 src/views/environment/envColumns.tsx:131
 #: src/views/notification/Notification.vue:37
-#: src/views/preference/AuthSettings.vue:26 src/views/stream/StreamList.vue:47
+#: src/views/preference/AuthSettings.vue:27 src/views/stream/StreamList.vue:47
 #: src/views/user/User.vue:43
 msgid "Action"
 msgstr "Action"
@@ -95,7 +99,7 @@ msgstr ""
 msgid "Arch"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:94
+#: src/views/preference/AuthSettings.vue:95
 #, fuzzy
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "Are you sure you want to remove this directive?"
@@ -153,7 +157,7 @@ msgstr ""
 msgid "Assistant"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:17
+#: src/views/preference/AuthSettings.vue:18
 msgid "Attempts"
 msgstr ""
 
@@ -198,15 +202,15 @@ msgstr "Back"
 msgid "Back to list"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:69
 msgid "Ban Threshold Minutes"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:83
 msgid "Banned IPs"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:20
+#: src/views/preference/AuthSettings.vue:21
 msgid "Banned Until"
 msgstr ""
 
@@ -405,6 +409,14 @@ msgstr ""
 msgid "Credentials"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:96
+msgid "Current account is enabled 2FA."
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:93
+msgid "Current account is not enabled 2FA."
+msgstr ""
+
 #: src/views/system/Upgrade.vue:167
 msgid "Current Version"
 msgstr ""
@@ -692,6 +704,16 @@ msgstr ""
 msgid "Enable %{conf_name} in %{node_name} successfully"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:122
+#, fuzzy
+msgid "Enable 2FA"
+msgstr "Enabled"
+
+#: src/views/preference/components/TOTP.vue:52
+#, fuzzy
+msgid "Enable 2FA successfully"
+msgstr "Enabled successfully"
+
 #: src/views/domain/cert/components/ObtainCert.vue:70
 msgid "Enable auto-renewal failed for %{name}"
 msgstr "Enable auto-renewal failed for %{name}"
@@ -893,12 +915,18 @@ msgstr ""
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:60
+#: src/views/preference/AuthSettings.vue:61
 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
+msgid ""
+"If you lose your mobile phone, you can use the recovery code to reset your "
+"2FA."
+msgstr ""
+
 #: src/views/certificate/Certificate.vue:136
 msgid "Import"
 msgstr ""
@@ -908,7 +936,7 @@ msgstr ""
 msgid "Import Certificate"
 msgstr "Certificate Status"
 
-#: src/views/other/Login.vue:59
+#: src/views/other/Login.vue:73
 msgid "Incorrect username or password"
 msgstr ""
 
@@ -924,7 +952,15 @@ msgstr ""
 msgid "Initialing core upgrader"
 msgstr ""
 
-#: src/routes/index.ts:273 src/views/other/Install.vue:135
+#: src/views/preference/components/TOTP.vue:144
+msgid "Input the code from the app:"
+msgstr ""
+
+#: src/views/other/Login.vue:194 src/views/preference/components/TOTP.vue:157
+msgid "Input the recovery code:"
+msgstr ""
+
+#: src/routes/index.ts:283 src/views/other/Install.vue:135
 msgid "Install"
 msgstr "Install"
 
@@ -946,7 +982,11 @@ msgstr ""
 msgid "Invalid"
 msgstr "Invalid E-mail!"
 
-#: src/views/preference/AuthSettings.vue:14
+#: src/views/other/Login.vue:83
+msgid "Invalid 2FA or recovery code"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:15
 msgid "IP"
 msgstr ""
 
@@ -1040,11 +1080,11 @@ msgstr "Locations"
 msgid "Log"
 msgstr "Login"
 
-#: src/routes/index.ts:279 src/views/other/Login.vue:159
+#: src/routes/index.ts:289 src/views/other/Login.vue:218
 msgid "Login"
 msgstr "Login"
 
-#: src/views/other/Login.vue:109 src/views/other/Login.vue:51
+#: src/views/other/Login.vue:127 src/views/other/Login.vue:62
 msgid "Login successful"
 msgstr "Login successful"
 
@@ -1088,7 +1128,7 @@ msgstr "Manage Sites"
 msgid "Manage Streams"
 msgstr "Manage Sites"
 
-#: src/routes/index.ts:230 src/views/user/User.vue:50
+#: src/routes/index.ts:235 src/views/user/User.vue:50
 msgid "Manage Users"
 msgstr "Manage Users"
 
@@ -1097,7 +1137,7 @@ msgstr "Manage Users"
 msgid "Managed Certificate"
 msgstr "Certificate is valid"
 
-#: src/views/preference/AuthSettings.vue:74
+#: src/views/preference/AuthSettings.vue:75
 msgid "Max Attempts"
 msgstr ""
 
@@ -1231,7 +1271,7 @@ msgstr "Saved successfully"
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/domain/ngx_conf/LocationEditor.vue:71
 #: src/views/notification/Notification.vue:70
-#: src/views/preference/AuthSettings.vue:96
+#: src/views/preference/AuthSettings.vue:97
 #: src/views/preference/BasicSettings.vue:101
 #: src/views/stream/StreamList.vue:165
 msgid "No"
@@ -1245,7 +1285,7 @@ msgstr ""
 msgid "Not After"
 msgstr ""
 
-#: src/routes/index.ts:285
+#: src/routes/index.ts:295
 msgid "Not Found"
 msgstr "Not Found"
 
@@ -1263,7 +1303,7 @@ msgstr ""
 msgid "Notification"
 msgstr "Certificate is valid"
 
-#: src/components/Notification/Notification.vue:82 src/routes/index.ts:221
+#: src/components/Notification/Notification.vue:82 src/routes/index.ts:226
 #, fuzzy
 msgid "Notifications"
 msgstr "Certificate is valid"
@@ -1346,7 +1386,7 @@ msgstr ""
 msgid "Params"
 msgstr "Params"
 
-#: src/views/other/Login.vue:144 src/views/user/User.vue:18
+#: src/views/other/Login.vue:167 src/views/user/User.vue:18
 msgid "Password"
 msgstr "Password"
 
@@ -1372,6 +1412,10 @@ msgstr ""
 msgid "Performing core upgrade"
 msgstr ""
 
+#: src/views/other/Login.vue:177
+msgid "Please enter the 2FA code:"
+msgstr ""
+
 #: src/views/certificate/DNSCredential.vue:53
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
@@ -1399,11 +1443,11 @@ msgstr ""
 msgid "Please input your E-mail!"
 msgstr "Please input your E-mail!"
 
-#: src/views/other/Install.vue:45 src/views/other/Login.vue:39
+#: src/views/other/Install.vue:45 src/views/other/Login.vue:45
 msgid "Please input your password!"
 msgstr "Please input your password!"
 
-#: src/views/other/Install.vue:39 src/views/other/Login.vue:33
+#: src/views/other/Install.vue:39 src/views/other/Login.vue:39
 msgid "Please input your username!"
 msgstr "Please input your username!"
 
@@ -1423,7 +1467,7 @@ msgstr ""
 msgid "Pre-release"
 msgstr ""
 
-#: src/routes/index.ts:239 src/views/preference/Preference.vue:105
+#: src/routes/index.ts:244 src/views/preference/Preference.vue:105
 msgid "Preference"
 msgstr ""
 
@@ -1467,6 +1511,18 @@ msgstr ""
 msgid "Recovered Successfully"
 msgstr "Saved successfully"
 
+#: src/views/other/Login.vue:204 src/views/preference/components/TOTP.vue:167
+msgid "Recovery"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:101
+msgid "Recovery Code"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:110
+msgid "Recovery Code:"
+msgstr ""
+
 #: src/views/preference/BasicSettings.vue:68
 msgid "Recursive Nameservers"
 msgstr ""
@@ -1519,11 +1575,11 @@ msgstr ""
 msgid "Reloading nginx"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:101
+#: src/views/preference/AuthSettings.vue:102
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:47
+#: src/views/preference/AuthSettings.vue:48
 #, fuzzy
 msgid "Remove successfully"
 msgstr "Saved successfully"
@@ -1568,6 +1624,10 @@ msgstr ""
 msgid "Reset"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:130
+msgid "Reset 2FA"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:93
 msgid "Restart"
 msgstr ""
@@ -1617,6 +1677,10 @@ msgstr "Saved successfully"
 msgid "Saved successfully"
 msgstr "Saved successfully"
 
+#: src/views/preference/components/TOTP.vue:91
+msgid "Scan the QR code with your mobile phone to add the account to the app."
+msgstr ""
+
 #: src/views/certificate/DNSChallenge.vue:89
 msgid "SDK"
 msgstr ""
@@ -1640,7 +1704,9 @@ msgstr "Send"
 #: src/views/config/ConfigEdit.vue:40 src/views/domain/DomainList.vue:81
 #: src/views/environment/BatchUpgrader.vue:57
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:69
-#: src/views/preference/AuthSettings.vue:49
+#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/components/TOTP.vue:42
+#: src/views/preference/components/TOTP.vue:55
 #: src/views/preference/Preference.vue:78 src/views/stream/StreamList.vue:113
 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1717,7 +1783,7 @@ msgstr "Certificate Status"
 msgid "SSL Certificate Path"
 msgstr "Certificate Status"
 
-#: src/views/other/Login.vue:170
+#: src/views/other/Login.vue:229
 #, fuzzy
 msgid "SSO Login"
 msgstr "Login"
@@ -1802,7 +1868,7 @@ msgstr "Certificate is valid"
 msgid "Sync to"
 msgstr ""
 
-#: src/routes/index.ts:248
+#: src/routes/index.ts:253
 msgid "System"
 msgstr ""
 
@@ -1856,6 +1922,11 @@ msgstr "Certificate Status"
 msgid "The path exists, but the file is not a private key"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:109
+msgid ""
+"The recovery code is only displayed once, please save it in a safe place."
+msgstr ""
+
 #: src/views/dashboard/Environments.vue:148
 msgid ""
 "The remote Nginx UI version is not compatible with the local Nginx UI "
@@ -1915,7 +1986,7 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:59
+#: src/views/preference/AuthSettings.vue:60
 #: src/views/preference/LogrotateSettings.vue:12
 msgid "Tips"
 msgstr ""
@@ -1924,6 +1995,12 @@ msgstr ""
 msgid "Title"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:90
+msgid ""
+"To enable it, you need to install the Google or Microsoft Authenticator app "
+"on your mobile phone."
+msgstr ""
+
 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:44
 msgid ""
 "To make sure the certification auto-renewal can work normally, we need to "
@@ -1936,10 +2013,16 @@ msgstr ""
 msgid "Token is not valid"
 msgstr ""
 
-#: src/views/other/Login.vue:62
+#: src/views/other/Login.vue:76
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:89
+msgid ""
+"TOTP is a two-factor authentication method that uses a time-based one-time "
+"password algorithm."
+msgstr ""
+
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:209
 msgid "Trash"
 msgstr ""
@@ -1964,7 +2047,7 @@ msgstr "Updated at"
 msgid "Updated successfully"
 msgstr "Saved successfully"
 
-#: src/routes/index.ts:263 src/views/environment/Environment.vue:50
+#: src/routes/index.ts:268 src/views/environment/Environment.vue:50
 #: src/views/system/Upgrade.vue:145 src/views/system/Upgrade.vue:228
 msgid "Upgrade"
 msgstr ""
@@ -1995,16 +2078,20 @@ msgstr "Uptime:"
 msgid "URL"
 msgstr ""
 
+#: src/views/other/Login.vue:186
+msgid "Use recovery code"
+msgstr ""
+
 #: src/components/ChatGPT/ChatGPT.vue:229
 #, fuzzy
 msgid "User"
 msgstr "Username"
 
-#: src/views/other/Login.vue:65
+#: src/views/other/Login.vue:79
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:134 src/views/user/User.vue:9
+#: src/views/other/Login.vue:157 src/views/user/User.vue:9
 msgid "Username"
 msgstr "Username"
 
@@ -2073,7 +2160,7 @@ msgstr ""
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/domain/ngx_conf/LocationEditor.vue:70
-#: src/views/preference/AuthSettings.vue:95
+#: src/views/preference/AuthSettings.vue:96
 #: src/views/preference/BasicSettings.vue:100
 msgid "Yes"
 msgstr "Yes"

+ 121 - 33
app/src/language/es/app.po

@@ -14,7 +14,11 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
 "X-Generator: Weblate 5.3.1\n"
 
-#: src/routes/index.ts:256
+#: src/views/preference/components/TOTP.vue:88
+msgid "2FA Settings"
+msgstr ""
+
+#: src/routes/index.ts:261
 msgid "About"
 msgstr "Acerca de"
 
@@ -33,7 +37,7 @@ msgstr "Usuario"
 #: src/views/certificate/DNSCredential.vue:33 src/views/config/config.ts:34
 #: src/views/domain/DomainList.vue:47 src/views/environment/envColumns.tsx:131
 #: src/views/notification/Notification.vue:37
-#: src/views/preference/AuthSettings.vue:26 src/views/stream/StreamList.vue:47
+#: src/views/preference/AuthSettings.vue:27 src/views/stream/StreamList.vue:47
 #: src/views/user/User.vue:43
 msgid "Action"
 msgstr "Acción"
@@ -98,7 +102,7 @@ msgstr "Token de la API"
 msgid "Arch"
 msgstr "Arquitectura"
 
-#: src/views/preference/AuthSettings.vue:94
+#: src/views/preference/AuthSettings.vue:95
 #, fuzzy
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "¿Está seguro de que quiere borrar?"
@@ -152,7 +156,7 @@ msgstr "Preguntar por ayuda a ChatGPT"
 msgid "Assistant"
 msgstr "Asistente"
 
-#: src/views/preference/AuthSettings.vue:17
+#: src/views/preference/AuthSettings.vue:18
 msgid "Attempts"
 msgstr ""
 
@@ -197,15 +201,15 @@ msgstr "Volver al Inicio"
 msgid "Back to list"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:69
 msgid "Ban Threshold Minutes"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:83
 msgid "Banned IPs"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:20
+#: src/views/preference/AuthSettings.vue:21
 msgid "Banned Until"
 msgstr ""
 
@@ -397,6 +401,14 @@ msgstr "Credencial"
 msgid "Credentials"
 msgstr "Credenciales"
 
+#: src/views/preference/components/TOTP.vue:96
+msgid "Current account is enabled 2FA."
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:93
+msgid "Current account is not enabled 2FA."
+msgstr ""
+
 #: src/views/system/Upgrade.vue:167
 msgid "Current Version"
 msgstr "Versión actual"
@@ -668,6 +680,16 @@ 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
+#, fuzzy
+msgid "Enable 2FA"
+msgstr "Habilitar"
+
+#: src/views/preference/components/TOTP.vue:52
+#, fuzzy
+msgid "Enable 2FA successfully"
+msgstr "Habilitado con Éxito"
+
 #: src/views/domain/cert/components/ObtainCert.vue:70
 msgid "Enable auto-renewal failed for %{name}"
 msgstr "No se pudo activar la renovación automática por %{name}"
@@ -863,12 +885,18 @@ msgstr "HTTP01"
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:60
+#: src/views/preference/AuthSettings.vue:61
 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
+msgid ""
+"If you lose your mobile phone, you can use the recovery code to reset your "
+"2FA."
+msgstr ""
+
 #: src/views/certificate/Certificate.vue:136
 msgid "Import"
 msgstr "Importar"
@@ -877,7 +905,7 @@ msgstr "Importar"
 msgid "Import Certificate"
 msgstr "Importar Certificado"
 
-#: src/views/other/Login.vue:59
+#: src/views/other/Login.vue:73
 #, fuzzy
 msgid "Incorrect username or password"
 msgstr "El nombre de usuario o contraseña son incorrectos"
@@ -894,7 +922,15 @@ msgstr "Error de actualización de kernel inicial"
 msgid "Initialing core upgrader"
 msgstr "Inicializando la actualización del kernel"
 
-#: src/routes/index.ts:273 src/views/other/Install.vue:135
+#: src/views/preference/components/TOTP.vue:144
+msgid "Input the code from the app:"
+msgstr ""
+
+#: src/views/other/Login.vue:194 src/views/preference/components/TOTP.vue:157
+msgid "Input the recovery code:"
+msgstr ""
+
+#: src/routes/index.ts:283 src/views/other/Install.vue:135
 msgid "Install"
 msgstr "Instalar"
 
@@ -915,7 +951,11 @@ msgstr ""
 msgid "Invalid"
 msgstr "Válido"
 
-#: src/views/preference/AuthSettings.vue:14
+#: src/views/other/Login.vue:83
+msgid "Invalid 2FA or recovery code"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:15
 msgid "IP"
 msgstr ""
 
@@ -1002,11 +1042,11 @@ msgstr "Ubicaciones"
 msgid "Log"
 msgstr "Registro"
 
-#: src/routes/index.ts:279 src/views/other/Login.vue:159
+#: src/routes/index.ts:289 src/views/other/Login.vue:218
 msgid "Login"
 msgstr "Acceso"
 
-#: src/views/other/Login.vue:109 src/views/other/Login.vue:51
+#: src/views/other/Login.vue:127 src/views/other/Login.vue:62
 msgid "Login successful"
 msgstr "Acceso exitoso"
 
@@ -1048,7 +1088,7 @@ msgstr "Administrar sitios"
 msgid "Manage Streams"
 msgstr "Administrar Transmisiones"
 
-#: src/routes/index.ts:230 src/views/user/User.vue:50
+#: src/routes/index.ts:235 src/views/user/User.vue:50
 msgid "Manage Users"
 msgstr "Administrar usuarios"
 
@@ -1056,7 +1096,7 @@ msgstr "Administrar usuarios"
 msgid "Managed Certificate"
 msgstr "Certificado Administrado"
 
-#: src/views/preference/AuthSettings.vue:74
+#: src/views/preference/AuthSettings.vue:75
 msgid "Max Attempts"
 msgstr ""
 
@@ -1184,7 +1224,7 @@ msgstr "Nginx reiniciado con éxito"
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/domain/ngx_conf/LocationEditor.vue:71
 #: src/views/notification/Notification.vue:70
-#: src/views/preference/AuthSettings.vue:96
+#: src/views/preference/AuthSettings.vue:97
 #: src/views/preference/BasicSettings.vue:101
 #: src/views/stream/StreamList.vue:165
 msgid "No"
@@ -1198,7 +1238,7 @@ msgstr "Secreto del nodo"
 msgid "Not After"
 msgstr "No después de"
 
-#: src/routes/index.ts:285
+#: src/routes/index.ts:295
 msgid "Not Found"
 msgstr "No encontrado"
 
@@ -1215,7 +1255,7 @@ msgstr "Nota"
 msgid "Notification"
 msgstr "Notificación"
 
-#: src/components/Notification/Notification.vue:82 src/routes/index.ts:221
+#: src/components/Notification/Notification.vue:82 src/routes/index.ts:226
 msgid "Notifications"
 msgstr "Notificaciones"
 
@@ -1295,7 +1335,7 @@ msgstr "Sobrescribir archivo existente"
 msgid "Params"
 msgstr "Parámetros"
 
-#: src/views/other/Login.vue:144 src/views/user/User.vue:18
+#: src/views/other/Login.vue:167 src/views/user/User.vue:18
 msgid "Password"
 msgstr "Contraseña"
 
@@ -1321,6 +1361,10 @@ msgstr "Error al ejecutar la actualización del kernel"
 msgid "Performing core upgrade"
 msgstr "Realizando la actualizaciónd el kernel"
 
+#: src/views/other/Login.vue:177
+msgid "Please enter the 2FA code:"
+msgstr ""
+
 #: src/views/certificate/DNSCredential.vue:53
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
@@ -1355,11 +1399,11 @@ msgstr ""
 msgid "Please input your E-mail!"
 msgstr "¡Por favor ingrese su correo electrónico!"
 
-#: src/views/other/Install.vue:45 src/views/other/Login.vue:39
+#: src/views/other/Install.vue:45 src/views/other/Login.vue:45
 msgid "Please input your password!"
 msgstr "¡Por favor ingrese su contraseña!"
 
-#: src/views/other/Install.vue:39 src/views/other/Login.vue:33
+#: src/views/other/Install.vue:39 src/views/other/Login.vue:39
 msgid "Please input your username!"
 msgstr "¡Por favor ingrese su nombre de usuario!"
 
@@ -1381,7 +1425,7 @@ msgstr "¡Seleccione al menos un nodo!"
 msgid "Pre-release"
 msgstr "Prelanzamiento"
 
-#: src/routes/index.ts:239 src/views/preference/Preference.vue:105
+#: src/routes/index.ts:244 src/views/preference/Preference.vue:105
 msgid "Preference"
 msgstr "Configuración"
 
@@ -1424,6 +1468,18 @@ msgstr ""
 msgid "Recovered Successfully"
 msgstr "Eliminado con éxito"
 
+#: src/views/other/Login.vue:204 src/views/preference/components/TOTP.vue:167
+msgid "Recovery"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:101
+msgid "Recovery Code"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:110
+msgid "Recovery Code:"
+msgstr ""
+
 #: src/views/preference/BasicSettings.vue:68
 msgid "Recursive Nameservers"
 msgstr ""
@@ -1477,11 +1533,11 @@ msgstr "Recargando"
 msgid "Reloading nginx"
 msgstr "Recargando Nginx"
 
-#: src/views/preference/AuthSettings.vue:101
+#: src/views/preference/AuthSettings.vue:102
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:47
+#: src/views/preference/AuthSettings.vue:48
 #, fuzzy
 msgid "Remove successfully"
 msgstr "Eliminado con éxito"
@@ -1520,6 +1576,11 @@ msgstr "Pedido con parámetros incorrectos"
 msgid "Reset"
 msgstr "Limpiar"
 
+#: src/views/preference/components/TOTP.vue:130
+#, fuzzy
+msgid "Reset 2FA"
+msgstr "Limpiar"
+
 #: src/components/NginxControl/NginxControl.vue:93
 msgid "Restart"
 msgstr "Reiniciar"
@@ -1567,6 +1628,10 @@ msgstr "Guardado con éxito"
 msgid "Saved successfully"
 msgstr "Guardado con éxito"
 
+#: src/views/preference/components/TOTP.vue:91
+msgid "Scan the QR code with your mobile phone to add the account to the app."
+msgstr ""
+
 #: src/views/certificate/DNSChallenge.vue:89
 msgid "SDK"
 msgstr ""
@@ -1590,7 +1655,9 @@ msgstr "Enviado"
 #: src/views/config/ConfigEdit.vue:40 src/views/domain/DomainList.vue:81
 #: src/views/environment/BatchUpgrader.vue:57
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:69
-#: src/views/preference/AuthSettings.vue:49
+#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/components/TOTP.vue:42
+#: src/views/preference/components/TOTP.vue:55
 #: src/views/preference/Preference.vue:78 src/views/stream/StreamList.vue:113
 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1662,7 +1729,7 @@ msgstr "Ruta de la llave del certificado SSL"
 msgid "SSL Certificate Path"
 msgstr "Ruta del certificado SSL"
 
-#: src/views/other/Login.vue:170
+#: src/views/other/Login.vue:229
 msgid "SSO Login"
 msgstr "Acceso SSO"
 
@@ -1744,7 +1811,7 @@ msgstr "Renovado de Certificado exitoso"
 msgid "Sync to"
 msgstr ""
 
-#: src/routes/index.ts:248
+#: src/routes/index.ts:253
 msgid "System"
 msgstr "Sistema"
 
@@ -1797,6 +1864,11 @@ msgstr "La ruta existe, pero el archivo no es una clave privada"
 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
+msgid ""
+"The recovery code is only displayed once, please save it in a safe place."
+msgstr ""
+
 #: src/views/dashboard/Environments.vue:148
 msgid ""
 "The remote Nginx UI version is not compatible with the local Nginx UI "
@@ -1857,7 +1929,7 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:59
+#: src/views/preference/AuthSettings.vue:60
 #: src/views/preference/LogrotateSettings.vue:12
 msgid "Tips"
 msgstr ""
@@ -1866,6 +1938,12 @@ msgstr ""
 msgid "Title"
 msgstr "Título"
 
+#: src/views/preference/components/TOTP.vue:90
+msgid ""
+"To enable it, you need to install the Google or Microsoft Authenticator app "
+"on your mobile phone."
+msgstr ""
+
 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:44
 msgid ""
 "To make sure the certification auto-renewal can work normally, we need to "
@@ -1882,10 +1960,16 @@ msgstr ""
 msgid "Token is not valid"
 msgstr "El token no es válido"
 
-#: src/views/other/Login.vue:62
+#: src/views/other/Login.vue:76
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:89
+msgid ""
+"TOTP is a two-factor authentication method that uses a time-based one-time "
+"password algorithm."
+msgstr ""
+
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:209
 msgid "Trash"
 msgstr ""
@@ -1909,7 +1993,7 @@ msgstr "Actualizado a"
 msgid "Updated successfully"
 msgstr "Actualización exitosa"
 
-#: src/routes/index.ts:263 src/views/environment/Environment.vue:50
+#: src/routes/index.ts:268 src/views/environment/Environment.vue:50
 #: src/views/system/Upgrade.vue:145 src/views/system/Upgrade.vue:228
 msgid "Upgrade"
 msgstr "Actualizar"
@@ -1939,15 +2023,19 @@ msgstr "Tiempo encendido:"
 msgid "URL"
 msgstr "URL"
 
+#: src/views/other/Login.vue:186
+msgid "Use recovery code"
+msgstr ""
+
 #: src/components/ChatGPT/ChatGPT.vue:229
 msgid "User"
 msgstr "Usuario"
 
-#: src/views/other/Login.vue:65
+#: src/views/other/Login.vue:79
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:134 src/views/user/User.vue:9
+#: src/views/other/Login.vue:157 src/views/user/User.vue:9
 msgid "Username"
 msgstr "Nombre de usuario"
 
@@ -2021,7 +2109,7 @@ msgstr "Escribir certificado a disco"
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/domain/ngx_conf/LocationEditor.vue:70
-#: src/views/preference/AuthSettings.vue:95
+#: src/views/preference/AuthSettings.vue:96
 #: src/views/preference/BasicSettings.vue:100
 msgid "Yes"
 msgstr "Si"

+ 121 - 33
app/src/language/fr_FR/app.po

@@ -11,7 +11,11 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: Poedit 3.3\n"
 
-#: src/routes/index.ts:256
+#: src/views/preference/components/TOTP.vue:88
+msgid "2FA Settings"
+msgstr ""
+
+#: src/routes/index.ts:261
 msgid "About"
 msgstr "À propos"
 
@@ -30,7 +34,7 @@ msgstr "Nom d'utilisateur"
 #: src/views/certificate/DNSCredential.vue:33 src/views/config/config.ts:34
 #: src/views/domain/DomainList.vue:47 src/views/environment/envColumns.tsx:131
 #: src/views/notification/Notification.vue:37
-#: src/views/preference/AuthSettings.vue:26 src/views/stream/StreamList.vue:47
+#: src/views/preference/AuthSettings.vue:27 src/views/stream/StreamList.vue:47
 #: src/views/user/User.vue:43
 msgid "Action"
 msgstr "Action"
@@ -99,7 +103,7 @@ msgstr "Jeton d'API"
 msgid "Arch"
 msgstr "Arch"
 
-#: src/views/preference/AuthSettings.vue:94
+#: src/views/preference/AuthSettings.vue:95
 #, fuzzy
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "Etes-vous sûr que vous voulez supprimer ?"
@@ -155,7 +159,7 @@ msgstr "Modèle ChatGPT"
 msgid "Assistant"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:17
+#: src/views/preference/AuthSettings.vue:18
 msgid "Attempts"
 msgstr ""
 
@@ -200,15 +204,15 @@ msgstr "Retour au menu principal"
 msgid "Back to list"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:69
 msgid "Ban Threshold Minutes"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:83
 msgid "Banned IPs"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:20
+#: src/views/preference/AuthSettings.vue:21
 msgid "Banned Until"
 msgstr ""
 
@@ -405,6 +409,14 @@ msgstr "Identifiant"
 msgid "Credentials"
 msgstr "Identifiants"
 
+#: src/views/preference/components/TOTP.vue:96
+msgid "Current account is enabled 2FA."
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:93
+msgid "Current account is not enabled 2FA."
+msgstr ""
+
 #: src/views/system/Upgrade.vue:167
 msgid "Current Version"
 msgstr "Version actuelle"
@@ -692,6 +704,16 @@ msgstr ""
 msgid "Enable %{conf_name} in %{node_name} successfully"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:122
+#, fuzzy
+msgid "Enable 2FA"
+msgstr "Activé"
+
+#: src/views/preference/components/TOTP.vue:52
+#, fuzzy
+msgid "Enable 2FA successfully"
+msgstr "Activé avec succès"
+
 #: src/views/domain/cert/components/ObtainCert.vue:70
 msgid "Enable auto-renewal failed for %{name}"
 msgstr "Échec de l'activation du renouvellement automatique pour %{name}"
@@ -894,12 +916,18 @@ msgstr "HTTP01"
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:60
+#: src/views/preference/AuthSettings.vue:61
 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
+msgid ""
+"If you lose your mobile phone, you can use the recovery code to reset your "
+"2FA."
+msgstr ""
+
 #: src/views/certificate/Certificate.vue:136
 #, fuzzy
 msgid "Import"
@@ -910,7 +938,7 @@ msgstr "Exporter"
 msgid "Import Certificate"
 msgstr "État du certificat"
 
-#: src/views/other/Login.vue:59
+#: src/views/other/Login.vue:73
 #, fuzzy
 msgid "Incorrect username or password"
 msgstr "Le pseudo ou mot de passe est incorect"
@@ -927,7 +955,15 @@ msgstr "Erreur du programme de mise à niveau initial du core"
 msgid "Initialing core upgrader"
 msgstr "Initialisation du programme de mise à niveau du core"
 
-#: src/routes/index.ts:273 src/views/other/Install.vue:135
+#: src/views/preference/components/TOTP.vue:144
+msgid "Input the code from the app:"
+msgstr ""
+
+#: src/views/other/Login.vue:194 src/views/preference/components/TOTP.vue:157
+msgid "Input the recovery code:"
+msgstr ""
+
+#: src/routes/index.ts:283 src/views/other/Install.vue:135
 msgid "Install"
 msgstr "Installer"
 
@@ -947,7 +983,11 @@ msgstr ""
 msgid "Invalid"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:14
+#: src/views/other/Login.vue:83
+msgid "Invalid 2FA or recovery code"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:15
 msgid "IP"
 msgstr ""
 
@@ -1043,11 +1083,11 @@ msgstr "Localisations"
 msgid "Log"
 msgstr "Connexion"
 
-#: src/routes/index.ts:279 src/views/other/Login.vue:159
+#: src/routes/index.ts:289 src/views/other/Login.vue:218
 msgid "Login"
 msgstr "Connexion"
 
-#: src/views/other/Login.vue:109 src/views/other/Login.vue:51
+#: src/views/other/Login.vue:127 src/views/other/Login.vue:62
 msgid "Login successful"
 msgstr "Connexion réussie"
 
@@ -1091,7 +1131,7 @@ msgstr "Gérer les sites"
 msgid "Manage Streams"
 msgstr "Gérer les sites"
 
-#: src/routes/index.ts:230 src/views/user/User.vue:50
+#: src/routes/index.ts:235 src/views/user/User.vue:50
 msgid "Manage Users"
 msgstr "Gérer les utilisateurs"
 
@@ -1100,7 +1140,7 @@ msgstr "Gérer les utilisateurs"
 msgid "Managed Certificate"
 msgstr "Changer de certificat"
 
-#: src/views/preference/AuthSettings.vue:74
+#: src/views/preference/AuthSettings.vue:75
 msgid "Max Attempts"
 msgstr ""
 
@@ -1230,7 +1270,7 @@ msgstr "Nginx a redémarré avec succès"
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/domain/ngx_conf/LocationEditor.vue:71
 #: src/views/notification/Notification.vue:70
-#: src/views/preference/AuthSettings.vue:96
+#: src/views/preference/AuthSettings.vue:97
 #: src/views/preference/BasicSettings.vue:101
 #: src/views/stream/StreamList.vue:165
 msgid "No"
@@ -1245,7 +1285,7 @@ msgstr "Secret Jwt"
 msgid "Not After"
 msgstr ""
 
-#: src/routes/index.ts:285
+#: src/routes/index.ts:295
 msgid "Not Found"
 msgstr "Introuvable"
 
@@ -1263,7 +1303,7 @@ msgstr "Note"
 msgid "Notification"
 msgstr "Certification"
 
-#: src/components/Notification/Notification.vue:82 src/routes/index.ts:221
+#: src/components/Notification/Notification.vue:82 src/routes/index.ts:226
 #, fuzzy
 msgid "Notifications"
 msgstr "Certification"
@@ -1344,7 +1384,7 @@ msgstr ""
 msgid "Params"
 msgstr "Paramètres"
 
-#: src/views/other/Login.vue:144 src/views/user/User.vue:18
+#: src/views/other/Login.vue:167 src/views/user/User.vue:18
 msgid "Password"
 msgstr "Mot de passe"
 
@@ -1370,6 +1410,10 @@ msgstr "Erreur lors de la mise a niveau du core"
 msgid "Performing core upgrade"
 msgstr "Exécution de la mise à niveau du core"
 
+#: src/views/other/Login.vue:177
+msgid "Please enter the 2FA code:"
+msgstr ""
+
 #: src/views/certificate/DNSCredential.vue:53
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
@@ -1404,11 +1448,11 @@ msgstr ""
 msgid "Please input your E-mail!"
 msgstr "Veuillez saisir votre e-mail !"
 
-#: src/views/other/Install.vue:45 src/views/other/Login.vue:39
+#: src/views/other/Install.vue:45 src/views/other/Login.vue:45
 msgid "Please input your password!"
 msgstr "Veuillez saisir votre mot de passe !"
 
-#: src/views/other/Install.vue:39 src/views/other/Login.vue:33
+#: src/views/other/Install.vue:39 src/views/other/Login.vue:39
 msgid "Please input your username!"
 msgstr "Veuillez saisir votre nom d'utilisateur !"
 
@@ -1428,7 +1472,7 @@ msgstr ""
 msgid "Pre-release"
 msgstr ""
 
-#: src/routes/index.ts:239 src/views/preference/Preference.vue:105
+#: src/routes/index.ts:244 src/views/preference/Preference.vue:105
 msgid "Preference"
 msgstr "Préférence"
 
@@ -1474,6 +1518,18 @@ msgstr ""
 msgid "Recovered Successfully"
 msgstr "Enregistré avec succès"
 
+#: src/views/other/Login.vue:204 src/views/preference/components/TOTP.vue:167
+msgid "Recovery"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:101
+msgid "Recovery Code"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:110
+msgid "Recovery Code:"
+msgstr ""
+
 #: src/views/preference/BasicSettings.vue:68
 msgid "Recursive Nameservers"
 msgstr ""
@@ -1527,11 +1583,11 @@ msgstr "Rechargement"
 msgid "Reloading nginx"
 msgstr "Rechargement de nginx"
 
-#: src/views/preference/AuthSettings.vue:101
+#: src/views/preference/AuthSettings.vue:102
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:47
+#: src/views/preference/AuthSettings.vue:48
 #, fuzzy
 msgid "Remove successfully"
 msgstr "Enregistré avec succès"
@@ -1576,6 +1632,11 @@ msgstr ""
 msgid "Reset"
 msgstr "Réinitialiser"
 
+#: src/views/preference/components/TOTP.vue:130
+#, fuzzy
+msgid "Reset 2FA"
+msgstr "Réinitialiser"
+
 #: src/components/NginxControl/NginxControl.vue:93
 msgid "Restart"
 msgstr "Redémarrer"
@@ -1623,6 +1684,10 @@ msgstr "Sauvegarde réussie"
 msgid "Saved successfully"
 msgstr "Enregistré avec succès"
 
+#: src/views/preference/components/TOTP.vue:91
+msgid "Scan the QR code with your mobile phone to add the account to the app."
+msgstr ""
+
 #: src/views/certificate/DNSChallenge.vue:89
 msgid "SDK"
 msgstr ""
@@ -1646,7 +1711,9 @@ msgstr "Envoyer"
 #: src/views/config/ConfigEdit.vue:40 src/views/domain/DomainList.vue:81
 #: src/views/environment/BatchUpgrader.vue:57
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:69
-#: src/views/preference/AuthSettings.vue:49
+#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/components/TOTP.vue:42
+#: src/views/preference/components/TOTP.vue:55
 #: src/views/preference/Preference.vue:78 src/views/stream/StreamList.vue:113
 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1722,7 +1789,7 @@ msgstr "Chemin de la clé du certificat SSL"
 msgid "SSL Certificate Path"
 msgstr "Chemin du certificat SSL"
 
-#: src/views/other/Login.vue:170
+#: src/views/other/Login.vue:229
 #, fuzzy
 msgid "SSO Login"
 msgstr "Connexion"
@@ -1808,7 +1875,7 @@ msgstr "Changer de certificat"
 msgid "Sync to"
 msgstr ""
 
-#: src/routes/index.ts:248
+#: src/routes/index.ts:253
 msgid "System"
 msgstr "Système"
 
@@ -1862,6 +1929,11 @@ 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
+msgid ""
+"The recovery code is only displayed once, please save it in a safe place."
+msgstr ""
+
 #: src/views/dashboard/Environments.vue:148
 msgid ""
 "The remote Nginx UI version is not compatible with the local Nginx UI "
@@ -1925,7 +1997,7 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:59
+#: src/views/preference/AuthSettings.vue:60
 #: src/views/preference/LogrotateSettings.vue:12
 msgid "Tips"
 msgstr ""
@@ -1934,6 +2006,12 @@ msgstr ""
 msgid "Title"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:90
+msgid ""
+"To enable it, you need to install the Google or Microsoft Authenticator app "
+"on your mobile phone."
+msgstr ""
+
 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:44
 msgid ""
 "To make sure the certification auto-renewal can work normally, we need to "
@@ -1950,10 +2028,16 @@ msgstr ""
 msgid "Token is not valid"
 msgstr ""
 
-#: src/views/other/Login.vue:62
+#: src/views/other/Login.vue:76
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:89
+msgid ""
+"TOTP is a two-factor authentication method that uses a time-based one-time "
+"password algorithm."
+msgstr ""
+
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:209
 msgid "Trash"
 msgstr ""
@@ -1977,7 +2061,7 @@ msgstr "Mis à jour le"
 msgid "Updated successfully"
 msgstr "Mis à jour avec succés"
 
-#: src/routes/index.ts:263 src/views/environment/Environment.vue:50
+#: src/routes/index.ts:268 src/views/environment/Environment.vue:50
 #: src/views/system/Upgrade.vue:145 src/views/system/Upgrade.vue:228
 msgid "Upgrade"
 msgstr "Mettre à niveau"
@@ -2007,16 +2091,20 @@ msgstr "Disponibilité :"
 msgid "URL"
 msgstr ""
 
+#: src/views/other/Login.vue:186
+msgid "Use recovery code"
+msgstr ""
+
 #: src/components/ChatGPT/ChatGPT.vue:229
 #, fuzzy
 msgid "User"
 msgstr "Nom d'utilisateur"
 
-#: src/views/other/Login.vue:65
+#: src/views/other/Login.vue:79
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:134 src/views/user/User.vue:9
+#: src/views/other/Login.vue:157 src/views/user/User.vue:9
 msgid "Username"
 msgstr "Nom d'utilisateur"
 
@@ -2088,7 +2176,7 @@ msgstr "Écriture du certificat sur le disque"
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/domain/ngx_conf/LocationEditor.vue:70
-#: src/views/preference/AuthSettings.vue:95
+#: src/views/preference/AuthSettings.vue:96
 #: src/views/preference/BasicSettings.vue:100
 msgid "Yes"
 msgstr "Oui"

+ 121 - 33
app/src/language/ko_KR/app.po

@@ -13,7 +13,11 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Generator: Weblate 5.3.1\n"
 
-#: src/routes/index.ts:256
+#: src/views/preference/components/TOTP.vue:88
+msgid "2FA Settings"
+msgstr ""
+
+#: src/routes/index.ts:261
 msgid "About"
 msgstr "소개"
 
@@ -32,7 +36,7 @@ msgstr "사용자 이름"
 #: src/views/certificate/DNSCredential.vue:33 src/views/config/config.ts:34
 #: src/views/domain/DomainList.vue:47 src/views/environment/envColumns.tsx:131
 #: src/views/notification/Notification.vue:37
-#: src/views/preference/AuthSettings.vue:26 src/views/stream/StreamList.vue:47
+#: src/views/preference/AuthSettings.vue:27 src/views/stream/StreamList.vue:47
 #: src/views/user/User.vue:43
 msgid "Action"
 msgstr "작업"
@@ -97,7 +101,7 @@ msgstr "API 토큰"
 msgid "Arch"
 msgstr "아키텍처"
 
-#: src/views/preference/AuthSettings.vue:94
+#: src/views/preference/AuthSettings.vue:95
 #, fuzzy
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "정말 삭제하시겠습니까?"
@@ -151,7 +155,7 @@ msgstr "ChatGPT에게 도움 요청"
 msgid "Assistant"
 msgstr "조수"
 
-#: src/views/preference/AuthSettings.vue:17
+#: src/views/preference/AuthSettings.vue:18
 msgid "Attempts"
 msgstr ""
 
@@ -196,15 +200,15 @@ msgstr "홈으로"
 msgid "Back to list"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:69
 msgid "Ban Threshold Minutes"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:83
 msgid "Banned IPs"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:20
+#: src/views/preference/AuthSettings.vue:21
 msgid "Banned Until"
 msgstr ""
 
@@ -395,6 +399,14 @@ msgstr "인증 정보"
 msgid "Credentials"
 msgstr "인증 정보들"
 
+#: src/views/preference/components/TOTP.vue:96
+msgid "Current account is enabled 2FA."
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:93
+msgid "Current account is not enabled 2FA."
+msgstr ""
+
 #: src/views/system/Upgrade.vue:167
 msgid "Current Version"
 msgstr "현재 버전"
@@ -666,6 +678,16 @@ 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
+#, fuzzy
+msgid "Enable 2FA"
+msgstr "활성화"
+
+#: src/views/preference/components/TOTP.vue:52
+#, fuzzy
+msgid "Enable 2FA successfully"
+msgstr "성공적으로 활성화"
+
 #: src/views/domain/cert/components/ObtainCert.vue:70
 msgid "Enable auto-renewal failed for %{name}"
 msgstr "%{name}에 대한 자동 갱신 활성화 실패"
@@ -866,12 +888,18 @@ msgstr "HTTP01"
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:60
+#: src/views/preference/AuthSettings.vue:61
 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
+msgid ""
+"If you lose your mobile phone, you can use the recovery code to reset your "
+"2FA."
+msgstr ""
+
 #: src/views/certificate/Certificate.vue:136
 msgid "Import"
 msgstr "가져오기"
@@ -881,7 +909,7 @@ msgstr "가져오기"
 msgid "Import Certificate"
 msgstr "인증서 상태"
 
-#: src/views/other/Login.vue:59
+#: src/views/other/Login.vue:73
 #, fuzzy
 msgid "Incorrect username or password"
 msgstr "사용자 이름 또는 비밀번호가 올바르지 않습니다"
@@ -898,7 +926,15 @@ msgstr "초기 코어 업그레이더 오류"
 msgid "Initialing core upgrader"
 msgstr "코어 업그레이더 초기화"
 
-#: src/routes/index.ts:273 src/views/other/Install.vue:135
+#: src/views/preference/components/TOTP.vue:144
+msgid "Input the code from the app:"
+msgstr ""
+
+#: src/views/other/Login.vue:194 src/views/preference/components/TOTP.vue:157
+msgid "Input the recovery code:"
+msgstr ""
+
+#: src/routes/index.ts:283 src/views/other/Install.vue:135
 msgid "Install"
 msgstr "설치"
 
@@ -920,7 +956,11 @@ msgstr "간격"
 msgid "Invalid"
 msgstr "유효함"
 
-#: src/views/preference/AuthSettings.vue:14
+#: src/views/other/Login.vue:83
+msgid "Invalid 2FA or recovery code"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:15
 msgid "IP"
 msgstr ""
 
@@ -1014,11 +1054,11 @@ msgstr "위치들"
 msgid "Log"
 msgstr "로그인"
 
-#: src/routes/index.ts:279 src/views/other/Login.vue:159
+#: src/routes/index.ts:289 src/views/other/Login.vue:218
 msgid "Login"
 msgstr "로그인"
 
-#: src/views/other/Login.vue:109 src/views/other/Login.vue:51
+#: src/views/other/Login.vue:127 src/views/other/Login.vue:62
 msgid "Login successful"
 msgstr "로그인 성공"
 
@@ -1067,7 +1107,7 @@ msgstr "사이트 관리"
 msgid "Manage Streams"
 msgstr "스트림 관리"
 
-#: src/routes/index.ts:230 src/views/user/User.vue:50
+#: src/routes/index.ts:235 src/views/user/User.vue:50
 msgid "Manage Users"
 msgstr "사용자 관리"
 
@@ -1076,7 +1116,7 @@ msgstr "사용자 관리"
 msgid "Managed Certificate"
 msgstr "인증서 유효"
 
-#: src/views/preference/AuthSettings.vue:74
+#: src/views/preference/AuthSettings.vue:75
 msgid "Max Attempts"
 msgstr ""
 
@@ -1210,7 +1250,7 @@ msgstr "Nginx가 성공적으로 재시작됨"
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/domain/ngx_conf/LocationEditor.vue:71
 #: src/views/notification/Notification.vue:70
-#: src/views/preference/AuthSettings.vue:96
+#: src/views/preference/AuthSettings.vue:97
 #: src/views/preference/BasicSettings.vue:101
 #: src/views/stream/StreamList.vue:165
 msgid "No"
@@ -1224,7 +1264,7 @@ msgstr "노드 시크릿"
 msgid "Not After"
 msgstr "만료일"
 
-#: src/routes/index.ts:285
+#: src/routes/index.ts:295
 msgid "Not Found"
 msgstr "찾을 수 없음"
 
@@ -1242,7 +1282,7 @@ msgstr "참고"
 msgid "Notification"
 msgstr "알림"
 
-#: src/components/Notification/Notification.vue:82 src/routes/index.ts:221
+#: src/components/Notification/Notification.vue:82 src/routes/index.ts:226
 #, fuzzy
 msgid "Notifications"
 msgstr "알림"
@@ -1325,7 +1365,7 @@ msgstr "기존 파일 덮어쓰기"
 msgid "Params"
 msgstr "파라미터"
 
-#: src/views/other/Login.vue:144 src/views/user/User.vue:18
+#: src/views/other/Login.vue:167 src/views/user/User.vue:18
 msgid "Password"
 msgstr "비밀번호"
 
@@ -1351,6 +1391,10 @@ msgstr "핵심 업그레이드 오류 수행"
 msgid "Performing core upgrade"
 msgstr "핵심 업그레이드 수행 중"
 
+#: src/views/other/Login.vue:177
+msgid "Please enter the 2FA code:"
+msgstr ""
+
 #: src/views/certificate/DNSCredential.vue:53
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
@@ -1380,11 +1424,11 @@ msgstr "이름을 입력해주세요, 이것은 새 구성의 파일 이름으
 msgid "Please input your E-mail!"
 msgstr "이메일을 입력해주세요!"
 
-#: src/views/other/Install.vue:45 src/views/other/Login.vue:39
+#: src/views/other/Install.vue:45 src/views/other/Login.vue:45
 msgid "Please input your password!"
 msgstr "비밀번호를 입력해주세요!"
 
-#: src/views/other/Install.vue:39 src/views/other/Login.vue:33
+#: src/views/other/Install.vue:39 src/views/other/Login.vue:39
 msgid "Please input your username!"
 msgstr "사용자 이름을 입력해주세요!"
 
@@ -1404,7 +1448,7 @@ msgstr "적어도 하나의 노드를 선택해주세요!"
 msgid "Pre-release"
 msgstr "사전 출시"
 
-#: src/routes/index.ts:239 src/views/preference/Preference.vue:105
+#: src/routes/index.ts:244 src/views/preference/Preference.vue:105
 msgid "Preference"
 msgstr "환경설정"
 
@@ -1448,6 +1492,18 @@ msgstr ""
 msgid "Recovered Successfully"
 msgstr "성공적으로 제거됨"
 
+#: src/views/other/Login.vue:204 src/views/preference/components/TOTP.vue:167
+msgid "Recovery"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:101
+msgid "Recovery Code"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:110
+msgid "Recovery Code:"
+msgstr ""
+
 #: src/views/preference/BasicSettings.vue:68
 msgid "Recursive Nameservers"
 msgstr ""
@@ -1502,11 +1558,11 @@ msgstr "리로딩 중"
 msgid "Reloading nginx"
 msgstr "Nginx 리로딩 중"
 
-#: src/views/preference/AuthSettings.vue:101
+#: src/views/preference/AuthSettings.vue:102
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:47
+#: src/views/preference/AuthSettings.vue:48
 #, fuzzy
 msgid "Remove successfully"
 msgstr "성공적으로 제거됨"
@@ -1551,6 +1607,11 @@ msgstr "잘못된 매개변수로 요청됨"
 msgid "Reset"
 msgstr "재설정"
 
+#: src/views/preference/components/TOTP.vue:130
+#, fuzzy
+msgid "Reset 2FA"
+msgstr "재설정"
+
 #: src/components/NginxControl/NginxControl.vue:93
 msgid "Restart"
 msgstr "재시작"
@@ -1600,6 +1661,10 @@ msgstr "성공적으로 저장됨"
 msgid "Saved successfully"
 msgstr "성공적으로 저장됨"
 
+#: src/views/preference/components/TOTP.vue:91
+msgid "Scan the QR code with your mobile phone to add the account to the app."
+msgstr ""
+
 #: src/views/certificate/DNSChallenge.vue:89
 msgid "SDK"
 msgstr ""
@@ -1623,7 +1688,9 @@ msgstr "보내기"
 #: src/views/config/ConfigEdit.vue:40 src/views/domain/DomainList.vue:81
 #: src/views/environment/BatchUpgrader.vue:57
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:69
-#: src/views/preference/AuthSettings.vue:49
+#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/components/TOTP.vue:42
+#: src/views/preference/components/TOTP.vue:55
 #: src/views/preference/Preference.vue:78 src/views/stream/StreamList.vue:113
 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1699,7 +1766,7 @@ msgstr "SSL 인증서 키 경로"
 msgid "SSL Certificate Path"
 msgstr "SSL 인증서 경로"
 
-#: src/views/other/Login.vue:170
+#: src/views/other/Login.vue:229
 #, fuzzy
 msgid "SSO Login"
 msgstr "SSO 로그인"
@@ -1784,7 +1851,7 @@ msgstr "인증서 갱신 성공"
 msgid "Sync to"
 msgstr ""
 
-#: src/routes/index.ts:248
+#: src/routes/index.ts:253
 msgid "System"
 msgstr "시스템"
 
@@ -1838,6 +1905,11 @@ msgstr "Certificate Status"
 msgid "The path exists, but the file is not a private key"
 msgstr "경로는 존재하지만 파일은 개인 키가 아닙니다"
 
+#: src/views/preference/components/TOTP.vue:109
+msgid ""
+"The recovery code is only displayed once, please save it in a safe place."
+msgstr ""
+
 #: src/views/dashboard/Environments.vue:148
 msgid ""
 "The remote Nginx UI version is not compatible with the local Nginx UI "
@@ -1899,7 +1971,7 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:59
+#: src/views/preference/AuthSettings.vue:60
 #: src/views/preference/LogrotateSettings.vue:12
 msgid "Tips"
 msgstr "팁"
@@ -1908,6 +1980,12 @@ msgstr "팁"
 msgid "Title"
 msgstr "제목"
 
+#: src/views/preference/components/TOTP.vue:90
+msgid ""
+"To enable it, you need to install the Google or Microsoft Authenticator app "
+"on your mobile phone."
+msgstr ""
+
 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:44
 msgid ""
 "To make sure the certification auto-renewal can work normally, we need to "
@@ -1923,10 +2001,16 @@ msgstr ""
 msgid "Token is not valid"
 msgstr "토큰이 유효하지 않습니다"
 
-#: src/views/other/Login.vue:62
+#: src/views/other/Login.vue:76
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:89
+msgid ""
+"TOTP is a two-factor authentication method that uses a time-based one-time "
+"password algorithm."
+msgstr ""
+
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:209
 msgid "Trash"
 msgstr ""
@@ -1951,7 +2035,7 @@ msgstr "업데이트됨"
 msgid "Updated successfully"
 msgstr "성공적으로 저장되었습니다"
 
-#: src/routes/index.ts:263 src/views/environment/Environment.vue:50
+#: src/routes/index.ts:268 src/views/environment/Environment.vue:50
 #: src/views/system/Upgrade.vue:145 src/views/system/Upgrade.vue:228
 msgid "Upgrade"
 msgstr "업그레이드"
@@ -1982,16 +2066,20 @@ msgstr "가동 시간:"
 msgid "URL"
 msgstr "URL"
 
+#: src/views/other/Login.vue:186
+msgid "Use recovery code"
+msgstr ""
+
 #: src/components/ChatGPT/ChatGPT.vue:229
 #, fuzzy
 msgid "User"
 msgstr "사용자 이름"
 
-#: src/views/other/Login.vue:65
+#: src/views/other/Login.vue:79
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:134 src/views/user/User.vue:9
+#: src/views/other/Login.vue:157 src/views/user/User.vue:9
 msgid "Username"
 msgstr "사용자 이름"
 
@@ -2066,7 +2154,7 @@ msgstr "인증서를 디스크에 쓰기"
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/domain/ngx_conf/LocationEditor.vue:70
-#: src/views/preference/AuthSettings.vue:95
+#: src/views/preference/AuthSettings.vue:96
 #: src/views/preference/BasicSettings.vue:100
 msgid "Yes"
 msgstr "예"

+ 115 - 35
app/src/language/messages.pot

@@ -2,7 +2,11 @@ msgid ""
 msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 
-#: src/routes/index.ts:256
+#: src/views/preference/components/TOTP.vue:88
+msgid "2FA Settings"
+msgstr ""
+
+#: src/routes/index.ts:261
 msgid "About"
 msgstr ""
 
@@ -24,7 +28,7 @@ msgstr ""
 #: src/views/domain/DomainList.vue:47
 #: src/views/environment/envColumns.tsx:131
 #: src/views/notification/Notification.vue:37
-#: src/views/preference/AuthSettings.vue:26
+#: src/views/preference/AuthSettings.vue:27
 #: src/views/stream/StreamList.vue:47
 #: src/views/user/User.vue:43
 msgid "Action"
@@ -91,7 +95,7 @@ msgstr ""
 msgid "Arch"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:94
+#: src/views/preference/AuthSettings.vue:95
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr ""
 
@@ -141,7 +145,7 @@ msgstr ""
 msgid "Assistant"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:17
+#: src/views/preference/AuthSettings.vue:18
 msgid "Attempts"
 msgstr ""
 
@@ -187,15 +191,15 @@ msgstr ""
 msgid "Back to list"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:69
 msgid "Ban Threshold Minutes"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:83
 msgid "Banned IPs"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:20
+#: src/views/preference/AuthSettings.vue:21
 msgid "Banned Until"
 msgstr ""
 
@@ -388,6 +392,14 @@ msgstr ""
 msgid "Credentials"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:96
+msgid "Current account is enabled 2FA."
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:93
+msgid "Current account is not enabled 2FA."
+msgstr ""
+
 #: src/views/system/Upgrade.vue:167
 msgid "Current Version"
 msgstr ""
@@ -662,6 +674,14 @@ msgstr ""
 msgid "Enable %{conf_name} in %{node_name} successfully"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:122
+msgid "Enable 2FA"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:52
+msgid "Enable 2FA successfully"
+msgstr ""
+
 #: src/views/domain/cert/components/ObtainCert.vue:70
 msgid "Enable auto-renewal failed for %{name}"
 msgstr ""
@@ -863,10 +883,14 @@ msgstr ""
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:60
+#: src/views/preference/AuthSettings.vue:61
 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
+msgid "If you lose your mobile phone, you can use the recovery code to reset your 2FA."
+msgstr ""
+
 #: src/views/certificate/Certificate.vue:136
 msgid "Import"
 msgstr ""
@@ -876,7 +900,7 @@ msgstr ""
 msgid "Import Certificate"
 msgstr ""
 
-#: src/views/other/Login.vue:59
+#: src/views/other/Login.vue:73
 msgid "Incorrect username or password"
 msgstr ""
 
@@ -892,7 +916,16 @@ msgstr ""
 msgid "Initialing core upgrader"
 msgstr ""
 
-#: src/routes/index.ts:273
+#: src/views/preference/components/TOTP.vue:144
+msgid "Input the code from the app:"
+msgstr ""
+
+#: src/views/other/Login.vue:194
+#: src/views/preference/components/TOTP.vue:157
+msgid "Input the recovery code:"
+msgstr ""
+
+#: src/routes/index.ts:283
 #: src/views/other/Install.vue:135
 msgid "Install"
 msgstr ""
@@ -913,7 +946,11 @@ msgstr ""
 msgid "Invalid"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:14
+#: src/views/other/Login.vue:83
+msgid "Invalid 2FA or recovery code"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:15
 msgid "IP"
 msgstr ""
 
@@ -998,13 +1035,13 @@ msgstr ""
 msgid "Log"
 msgstr ""
 
-#: src/routes/index.ts:279
-#: src/views/other/Login.vue:159
+#: src/routes/index.ts:289
+#: src/views/other/Login.vue:218
 msgid "Login"
 msgstr ""
 
-#: src/views/other/Login.vue:109
-#: src/views/other/Login.vue:51
+#: src/views/other/Login.vue:127
+#: src/views/other/Login.vue:62
 msgid "Login successful"
 msgstr ""
 
@@ -1038,7 +1075,7 @@ msgstr ""
 msgid "Manage Streams"
 msgstr ""
 
-#: src/routes/index.ts:230
+#: src/routes/index.ts:235
 #: src/views/user/User.vue:50
 msgid "Manage Users"
 msgstr ""
@@ -1047,7 +1084,7 @@ msgstr ""
 msgid "Managed Certificate"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:74
+#: src/views/preference/AuthSettings.vue:75
 msgid "Max Attempts"
 msgstr ""
 
@@ -1178,7 +1215,7 @@ msgstr ""
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/domain/ngx_conf/LocationEditor.vue:71
 #: src/views/notification/Notification.vue:70
-#: src/views/preference/AuthSettings.vue:96
+#: src/views/preference/AuthSettings.vue:97
 #: src/views/preference/BasicSettings.vue:101
 #: src/views/stream/StreamList.vue:165
 msgid "No"
@@ -1192,7 +1229,7 @@ msgstr ""
 msgid "Not After"
 msgstr ""
 
-#: src/routes/index.ts:285
+#: src/routes/index.ts:295
 msgid "Not Found"
 msgstr ""
 
@@ -1210,7 +1247,7 @@ msgid "Notification"
 msgstr ""
 
 #: src/components/Notification/Notification.vue:82
-#: src/routes/index.ts:221
+#: src/routes/index.ts:226
 msgid "Notifications"
 msgstr ""
 
@@ -1290,7 +1327,7 @@ msgstr ""
 msgid "Params"
 msgstr ""
 
-#: src/views/other/Login.vue:144
+#: src/views/other/Login.vue:167
 #: src/views/user/User.vue:18
 msgid "Password"
 msgstr ""
@@ -1317,6 +1354,10 @@ msgstr ""
 msgid "Performing core upgrade"
 msgstr ""
 
+#: src/views/other/Login.vue:177
+msgid "Please enter the 2FA code:"
+msgstr ""
+
 #: src/views/certificate/DNSCredential.vue:53
 msgid "Please fill in the API authentication credentials provided by your DNS provider."
 msgstr ""
@@ -1339,12 +1380,12 @@ msgid "Please input your E-mail!"
 msgstr ""
 
 #: src/views/other/Install.vue:45
-#: src/views/other/Login.vue:39
+#: src/views/other/Login.vue:45
 msgid "Please input your password!"
 msgstr ""
 
 #: src/views/other/Install.vue:39
-#: src/views/other/Login.vue:33
+#: src/views/other/Login.vue:39
 msgid "Please input your username!"
 msgstr ""
 
@@ -1364,7 +1405,7 @@ msgstr ""
 msgid "Pre-release"
 msgstr ""
 
-#: src/routes/index.ts:239
+#: src/routes/index.ts:244
 #: src/views/preference/Preference.vue:105
 msgid "Preference"
 msgstr ""
@@ -1407,6 +1448,19 @@ msgstr ""
 msgid "Recovered Successfully"
 msgstr ""
 
+#: src/views/other/Login.vue:204
+#: src/views/preference/components/TOTP.vue:167
+msgid "Recovery"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:101
+msgid "Recovery Code"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:110
+msgid "Recovery Code:"
+msgstr ""
+
 #: src/views/preference/BasicSettings.vue:68
 msgid "Recursive Nameservers"
 msgstr ""
@@ -1456,11 +1510,11 @@ msgstr ""
 msgid "Reloading nginx"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:101
+#: src/views/preference/AuthSettings.vue:102
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:47
+#: src/views/preference/AuthSettings.vue:48
 msgid "Remove successfully"
 msgstr ""
 
@@ -1498,6 +1552,10 @@ msgstr ""
 msgid "Reset"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:130
+msgid "Reset 2FA"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:93
 msgid "Restart"
 msgstr ""
@@ -1549,6 +1607,10 @@ msgstr ""
 msgid "Saved successfully"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:91
+msgid "Scan the QR code with your mobile phone to add the account to the app."
+msgstr ""
+
 #: src/views/certificate/DNSChallenge.vue:89
 msgid "SDK"
 msgstr ""
@@ -1574,7 +1636,9 @@ msgstr ""
 #: src/views/environment/BatchUpgrader.vue:57
 #: src/views/environment/Environment.vue:15
 #: src/views/other/Install.vue:69
-#: src/views/preference/AuthSettings.vue:49
+#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/components/TOTP.vue:42
+#: src/views/preference/components/TOTP.vue:55
 #: src/views/preference/Preference.vue:78
 #: src/views/stream/StreamList.vue:113
 #: src/views/stream/StreamList.vue:81
@@ -1645,7 +1709,7 @@ msgstr ""
 msgid "SSL Certificate Path"
 msgstr ""
 
-#: src/views/other/Login.vue:170
+#: src/views/other/Login.vue:229
 msgid "SSO Login"
 msgstr ""
 
@@ -1722,7 +1786,7 @@ msgstr ""
 msgid "Sync to"
 msgstr ""
 
-#: src/routes/index.ts:248
+#: src/routes/index.ts:253
 msgid "System"
 msgstr ""
 
@@ -1768,6 +1832,10 @@ msgstr ""
 msgid "The path exists, but the file is not a private key"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:109
+msgid "The recovery code is only displayed once, please save it in a safe place."
+msgstr ""
+
 #: src/views/dashboard/Environments.vue:148
 msgid "The remote Nginx UI version is not compatible with the local Nginx UI version. To avoid potential errors, please upgrade the remote Nginx UI to match the local version."
 msgstr ""
@@ -1816,7 +1884,7 @@ msgstr ""
 msgid "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:59
+#: src/views/preference/AuthSettings.vue:60
 #: src/views/preference/LogrotateSettings.vue:12
 msgid "Tips"
 msgstr ""
@@ -1825,6 +1893,10 @@ msgstr ""
 msgid "Title"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:90
+msgid "To enable it, you need to install the Google or Microsoft Authenticator app on your mobile phone."
+msgstr ""
+
 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:44
 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 ""
@@ -1833,10 +1905,14 @@ msgstr ""
 msgid "Token is not valid"
 msgstr ""
 
-#: src/views/other/Login.vue:62
+#: src/views/other/Login.vue:76
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:89
+msgid "TOTP is a two-factor authentication method that uses a time-based one-time password algorithm."
+msgstr ""
+
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:209
 msgid "Trash"
 msgstr ""
@@ -1864,7 +1940,7 @@ msgstr ""
 msgid "Updated successfully"
 msgstr ""
 
-#: src/routes/index.ts:263
+#: src/routes/index.ts:268
 #: src/views/environment/Environment.vue:50
 #: src/views/system/Upgrade.vue:145
 #: src/views/system/Upgrade.vue:228
@@ -1896,15 +1972,19 @@ msgstr ""
 msgid "URL"
 msgstr ""
 
+#: src/views/other/Login.vue:186
+msgid "Use recovery code"
+msgstr ""
+
 #: src/components/ChatGPT/ChatGPT.vue:229
 msgid "User"
 msgstr ""
 
-#: src/views/other/Login.vue:65
+#: src/views/other/Login.vue:79
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:134
+#: src/views/other/Login.vue:157
 #: src/views/user/User.vue:9
 msgid "Username"
 msgstr ""
@@ -1969,7 +2049,7 @@ msgstr ""
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/domain/ngx_conf/LocationEditor.vue:70
-#: src/views/preference/AuthSettings.vue:95
+#: src/views/preference/AuthSettings.vue:96
 #: src/views/preference/BasicSettings.vue:100
 msgid "Yes"
 msgstr ""

+ 121 - 33
app/src/language/ru_RU/app.po

@@ -9,7 +9,11 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/routes/index.ts:256
+#: src/views/preference/components/TOTP.vue:88
+msgid "2FA Settings"
+msgstr ""
+
+#: src/routes/index.ts:261
 msgid "About"
 msgstr "О проекте"
 
@@ -28,7 +32,7 @@ msgstr "Пользователь"
 #: src/views/certificate/DNSCredential.vue:33 src/views/config/config.ts:34
 #: src/views/domain/DomainList.vue:47 src/views/environment/envColumns.tsx:131
 #: src/views/notification/Notification.vue:37
-#: src/views/preference/AuthSettings.vue:26 src/views/stream/StreamList.vue:47
+#: src/views/preference/AuthSettings.vue:27 src/views/stream/StreamList.vue:47
 #: src/views/user/User.vue:43
 msgid "Action"
 msgstr "Действие"
@@ -95,7 +99,7 @@ msgstr ""
 msgid "Arch"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:94
+#: src/views/preference/AuthSettings.vue:95
 #, fuzzy
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "Вы уверены, что хотите удалить?"
@@ -153,7 +157,7 @@ msgstr "Обратитесь за помощью к ChatGPT"
 msgid "Assistant"
 msgstr "Ассистент"
 
-#: src/views/preference/AuthSettings.vue:17
+#: src/views/preference/AuthSettings.vue:18
 msgid "Attempts"
 msgstr ""
 
@@ -199,15 +203,15 @@ msgstr "Вернутся"
 msgid "Back to list"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:69
 msgid "Ban Threshold Minutes"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:83
 msgid "Banned IPs"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:20
+#: src/views/preference/AuthSettings.vue:21
 msgid "Banned Until"
 msgstr ""
 
@@ -407,6 +411,14 @@ msgstr "Учетные данные"
 msgid "Credentials"
 msgstr "Учетные данные"
 
+#: src/views/preference/components/TOTP.vue:96
+msgid "Current account is enabled 2FA."
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:93
+msgid "Current account is not enabled 2FA."
+msgstr ""
+
 #: src/views/system/Upgrade.vue:167
 msgid "Current Version"
 msgstr "Текущяя версия"
@@ -696,6 +708,16 @@ 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
+#, fuzzy
+msgid "Enable 2FA"
+msgstr "Включить"
+
+#: src/views/preference/components/TOTP.vue:52
+#, fuzzy
+msgid "Enable 2FA successfully"
+msgstr "Активировано успешно"
+
 #: src/views/domain/cert/components/ObtainCert.vue:70
 msgid "Enable auto-renewal failed for %{name}"
 msgstr "Не удалось включить автоматическое продление для %{name}"
@@ -898,12 +920,18 @@ msgstr ""
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:60
+#: src/views/preference/AuthSettings.vue:61
 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
+msgid ""
+"If you lose your mobile phone, you can use the recovery code to reset your "
+"2FA."
+msgstr ""
+
 #: src/views/certificate/Certificate.vue:136
 #, fuzzy
 msgid "Import"
@@ -914,7 +942,7 @@ msgstr "Экспорт"
 msgid "Import Certificate"
 msgstr "Статус сертификата"
 
-#: src/views/other/Login.vue:59
+#: src/views/other/Login.vue:73
 #, fuzzy
 msgid "Incorrect username or password"
 msgstr "Имя пользователя или пароль неверны"
@@ -931,7 +959,15 @@ msgstr "Ошибка первоначального обновления ядр
 msgid "Initialing core upgrader"
 msgstr "Инициализация программы обновления ядра"
 
-#: src/routes/index.ts:273 src/views/other/Install.vue:135
+#: src/views/preference/components/TOTP.vue:144
+msgid "Input the code from the app:"
+msgstr ""
+
+#: src/views/other/Login.vue:194 src/views/preference/components/TOTP.vue:157
+msgid "Input the recovery code:"
+msgstr ""
+
+#: src/routes/index.ts:283 src/views/other/Install.vue:135
 msgid "Install"
 msgstr "Установить"
 
@@ -953,7 +989,11 @@ msgstr ""
 msgid "Invalid"
 msgstr "Действительный"
 
-#: src/views/preference/AuthSettings.vue:14
+#: src/views/other/Login.vue:83
+msgid "Invalid 2FA or recovery code"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:15
 msgid "IP"
 msgstr ""
 
@@ -1048,11 +1088,11 @@ msgstr "Locations"
 msgid "Log"
 msgstr "Логин"
 
-#: src/routes/index.ts:279 src/views/other/Login.vue:159
+#: src/routes/index.ts:289 src/views/other/Login.vue:218
 msgid "Login"
 msgstr "Логин"
 
-#: src/views/other/Login.vue:109 src/views/other/Login.vue:51
+#: src/views/other/Login.vue:127 src/views/other/Login.vue:62
 msgid "Login successful"
 msgstr "Авторизация успешна"
 
@@ -1096,7 +1136,7 @@ msgstr "Сайты"
 msgid "Manage Streams"
 msgstr "Управление потоками"
 
-#: src/routes/index.ts:230 src/views/user/User.vue:50
+#: src/routes/index.ts:235 src/views/user/User.vue:50
 msgid "Manage Users"
 msgstr "Пользователи"
 
@@ -1105,7 +1145,7 @@ msgstr "Пользователи"
 msgid "Managed Certificate"
 msgstr "Управление сертификатами"
 
-#: src/views/preference/AuthSettings.vue:74
+#: src/views/preference/AuthSettings.vue:75
 msgid "Max Attempts"
 msgstr ""
 
@@ -1240,7 +1280,7 @@ msgstr "Nginx успешно перезапущен"
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/domain/ngx_conf/LocationEditor.vue:71
 #: src/views/notification/Notification.vue:70
-#: src/views/preference/AuthSettings.vue:96
+#: src/views/preference/AuthSettings.vue:97
 #: src/views/preference/BasicSettings.vue:101
 #: src/views/stream/StreamList.vue:165
 msgid "No"
@@ -1254,7 +1294,7 @@ msgstr ""
 msgid "Not After"
 msgstr ""
 
-#: src/routes/index.ts:285
+#: src/routes/index.ts:295
 msgid "Not Found"
 msgstr "Не найден"
 
@@ -1272,7 +1312,7 @@ msgstr "Заметка"
 msgid "Notification"
 msgstr "Сертификат"
 
-#: src/components/Notification/Notification.vue:82 src/routes/index.ts:221
+#: src/components/Notification/Notification.vue:82 src/routes/index.ts:226
 #, fuzzy
 msgid "Notifications"
 msgstr "Уведомления"
@@ -1355,7 +1395,7 @@ msgstr ""
 msgid "Params"
 msgstr "Параметры"
 
-#: src/views/other/Login.vue:144 src/views/user/User.vue:18
+#: src/views/other/Login.vue:167 src/views/user/User.vue:18
 msgid "Password"
 msgstr "Пароль"
 
@@ -1381,6 +1421,10 @@ msgstr ""
 msgid "Performing core upgrade"
 msgstr ""
 
+#: src/views/other/Login.vue:177
+msgid "Please enter the 2FA code:"
+msgstr ""
+
 #: src/views/certificate/DNSCredential.vue:53
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
@@ -1410,11 +1454,11 @@ msgstr ""
 msgid "Please input your E-mail!"
 msgstr "Введите ваш E-mail!"
 
-#: src/views/other/Install.vue:45 src/views/other/Login.vue:39
+#: src/views/other/Install.vue:45 src/views/other/Login.vue:45
 msgid "Please input your password!"
 msgstr "Введите ваш пароль!"
 
-#: src/views/other/Install.vue:39 src/views/other/Login.vue:33
+#: src/views/other/Install.vue:39 src/views/other/Login.vue:39
 msgid "Please input your username!"
 msgstr "Введите ваше имя пользователя!"
 
@@ -1434,7 +1478,7 @@ msgstr ""
 msgid "Pre-release"
 msgstr ""
 
-#: src/routes/index.ts:239 src/views/preference/Preference.vue:105
+#: src/routes/index.ts:244 src/views/preference/Preference.vue:105
 msgid "Preference"
 msgstr "Настройки"
 
@@ -1478,6 +1522,18 @@ msgstr ""
 msgid "Recovered Successfully"
 msgstr "Успешно сохранено"
 
+#: src/views/other/Login.vue:204 src/views/preference/components/TOTP.vue:167
+msgid "Recovery"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:101
+msgid "Recovery Code"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:110
+msgid "Recovery Code:"
+msgstr ""
+
 #: src/views/preference/BasicSettings.vue:68
 msgid "Recursive Nameservers"
 msgstr ""
@@ -1532,11 +1588,11 @@ msgstr "Перезагружается"
 msgid "Reloading nginx"
 msgstr "Перезагружается nginx"
 
-#: src/views/preference/AuthSettings.vue:101
+#: src/views/preference/AuthSettings.vue:102
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:47
+#: src/views/preference/AuthSettings.vue:48
 #, fuzzy
 msgid "Remove successfully"
 msgstr "Успешно сохранено"
@@ -1581,6 +1637,11 @@ msgstr "Запрос с неправильными параметрами"
 msgid "Reset"
 msgstr "Сброс"
 
+#: src/views/preference/components/TOTP.vue:130
+#, fuzzy
+msgid "Reset 2FA"
+msgstr "Сброс"
+
 #: src/components/NginxControl/NginxControl.vue:93
 msgid "Restart"
 msgstr "Перезапуск"
@@ -1630,6 +1691,10 @@ msgstr "Успешно сохранено"
 msgid "Saved successfully"
 msgstr "Успешно сохранено"
 
+#: src/views/preference/components/TOTP.vue:91
+msgid "Scan the QR code with your mobile phone to add the account to the app."
+msgstr ""
+
 #: src/views/certificate/DNSChallenge.vue:89
 msgid "SDK"
 msgstr ""
@@ -1653,7 +1718,9 @@ msgstr "Отправлено"
 #: src/views/config/ConfigEdit.vue:40 src/views/domain/DomainList.vue:81
 #: src/views/environment/BatchUpgrader.vue:57
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:69
-#: src/views/preference/AuthSettings.vue:49
+#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/components/TOTP.vue:42
+#: src/views/preference/components/TOTP.vue:55
 #: src/views/preference/Preference.vue:78 src/views/stream/StreamList.vue:113
 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1730,7 +1797,7 @@ msgstr "Путь к ключу сертификата SSL"
 msgid "SSL Certificate Path"
 msgstr "Путь к сертификату SSL"
 
-#: src/views/other/Login.vue:170
+#: src/views/other/Login.vue:229
 #, fuzzy
 msgid "SSO Login"
 msgstr "Логин"
@@ -1815,7 +1882,7 @@ msgstr "Сертификат действителен"
 msgid "Sync to"
 msgstr ""
 
-#: src/routes/index.ts:248
+#: src/routes/index.ts:253
 msgid "System"
 msgstr "Система"
 
@@ -1869,6 +1936,11 @@ msgstr "Путь к ключу сертификата SSL"
 msgid "The path exists, but the file is not a private key"
 msgstr "Путь существует, но файл не является приватным ключом"
 
+#: src/views/preference/components/TOTP.vue:109
+msgid ""
+"The recovery code is only displayed once, please save it in a safe place."
+msgstr ""
+
 #: src/views/dashboard/Environments.vue:148
 msgid ""
 "The remote Nginx UI version is not compatible with the local Nginx UI "
@@ -1931,7 +2003,7 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:59
+#: src/views/preference/AuthSettings.vue:60
 #: src/views/preference/LogrotateSettings.vue:12
 msgid "Tips"
 msgstr ""
@@ -1940,6 +2012,12 @@ msgstr ""
 msgid "Title"
 msgstr "Заголовок"
 
+#: src/views/preference/components/TOTP.vue:90
+msgid ""
+"To enable it, you need to install the Google or Microsoft Authenticator app "
+"on your mobile phone."
+msgstr ""
+
 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:44
 msgid ""
 "To make sure the certification auto-renewal can work normally, we need to "
@@ -1952,10 +2030,16 @@ msgstr ""
 msgid "Token is not valid"
 msgstr ""
 
-#: src/views/other/Login.vue:62
+#: src/views/other/Login.vue:76
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:89
+msgid ""
+"TOTP is a two-factor authentication method that uses a time-based one-time "
+"password algorithm."
+msgstr ""
+
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:209
 msgid "Trash"
 msgstr ""
@@ -1980,7 +2064,7 @@ msgstr "Обновлено в"
 msgid "Updated successfully"
 msgstr "Обновлено успешно"
 
-#: src/routes/index.ts:263 src/views/environment/Environment.vue:50
+#: src/routes/index.ts:268 src/views/environment/Environment.vue:50
 #: src/views/system/Upgrade.vue:145 src/views/system/Upgrade.vue:228
 msgid "Upgrade"
 msgstr "Обновление"
@@ -2011,16 +2095,20 @@ msgstr "Аптайм:"
 msgid "URL"
 msgstr ""
 
+#: src/views/other/Login.vue:186
+msgid "Use recovery code"
+msgstr ""
+
 #: src/components/ChatGPT/ChatGPT.vue:229
 #, fuzzy
 msgid "User"
 msgstr "Пользователь"
 
-#: src/views/other/Login.vue:65
+#: src/views/other/Login.vue:79
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:134 src/views/user/User.vue:9
+#: src/views/other/Login.vue:157 src/views/user/User.vue:9
 msgid "Username"
 msgstr "Имя пользователя"
 
@@ -2092,7 +2180,7 @@ msgstr "Запись сертификата на диск"
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/domain/ngx_conf/LocationEditor.vue:70
-#: src/views/preference/AuthSettings.vue:95
+#: src/views/preference/AuthSettings.vue:96
 #: src/views/preference/BasicSettings.vue:100
 msgid "Yes"
 msgstr "Да"

+ 121 - 33
app/src/language/vi_VN/app.po

@@ -9,7 +9,11 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/routes/index.ts:256
+#: src/views/preference/components/TOTP.vue:88
+msgid "2FA Settings"
+msgstr ""
+
+#: src/routes/index.ts:261
 msgid "About"
 msgstr "Tác giả"
 
@@ -28,7 +32,7 @@ msgstr "Người dùng"
 #: src/views/certificate/DNSCredential.vue:33 src/views/config/config.ts:34
 #: src/views/domain/DomainList.vue:47 src/views/environment/envColumns.tsx:131
 #: src/views/notification/Notification.vue:37
-#: src/views/preference/AuthSettings.vue:26 src/views/stream/StreamList.vue:47
+#: src/views/preference/AuthSettings.vue:27 src/views/stream/StreamList.vue:47
 #: src/views/user/User.vue:43
 msgid "Action"
 msgstr "Hành động"
@@ -95,7 +99,7 @@ msgstr ""
 msgid "Arch"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:94
+#: src/views/preference/AuthSettings.vue:95
 #, fuzzy
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "Bạn chắc chắn muốn xóa nó "
@@ -153,7 +157,7 @@ msgstr "Hỏi ChatGPT"
 msgid "Assistant"
 msgstr "Trợ lý"
 
-#: src/views/preference/AuthSettings.vue:17
+#: src/views/preference/AuthSettings.vue:18
 msgid "Attempts"
 msgstr ""
 
@@ -199,15 +203,15 @@ msgstr "Quay lại"
 msgid "Back to list"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:69
 msgid "Ban Threshold Minutes"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:83
 msgid "Banned IPs"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:20
+#: src/views/preference/AuthSettings.vue:21
 msgid "Banned Until"
 msgstr ""
 
@@ -407,6 +411,14 @@ msgstr "Chứng chỉ"
 msgid "Credentials"
 msgstr "Chứng chỉ"
 
+#: src/views/preference/components/TOTP.vue:96
+msgid "Current account is enabled 2FA."
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:93
+msgid "Current account is not enabled 2FA."
+msgstr ""
+
 #: src/views/system/Upgrade.vue:167
 msgid "Current Version"
 msgstr "Phiên bản hiện tại"
@@ -697,6 +709,16 @@ 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
+#, fuzzy
+msgid "Enable 2FA"
+msgstr "Đã bật"
+
+#: src/views/preference/components/TOTP.vue:52
+#, fuzzy
+msgid "Enable 2FA successfully"
+msgstr "Đã bật"
+
 #: src/views/domain/cert/components/ObtainCert.vue:70
 msgid "Enable auto-renewal failed for %{name}"
 msgstr "Không thể bật tự động gia hạn SSL cho %{name}"
@@ -900,12 +922,18 @@ msgstr ""
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:60
+#: src/views/preference/AuthSettings.vue:61
 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
+msgid ""
+"If you lose your mobile phone, you can use the recovery code to reset your "
+"2FA."
+msgstr ""
+
 #: src/views/certificate/Certificate.vue:136
 #, fuzzy
 msgid "Import"
@@ -916,7 +944,7 @@ msgstr "Xuất"
 msgid "Import Certificate"
 msgstr "Chứng chỉ"
 
-#: src/views/other/Login.vue:59
+#: src/views/other/Login.vue:73
 #, fuzzy
 msgid "Incorrect username or password"
 msgstr "Tên người dùng hoặc mật khẩu không chính xác"
@@ -933,7 +961,15 @@ 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/routes/index.ts:273 src/views/other/Install.vue:135
+#: src/views/preference/components/TOTP.vue:144
+msgid "Input the code from the app:"
+msgstr ""
+
+#: src/views/other/Login.vue:194 src/views/preference/components/TOTP.vue:157
+msgid "Input the recovery code:"
+msgstr ""
+
+#: src/routes/index.ts:283 src/views/other/Install.vue:135
 msgid "Install"
 msgstr "Cài đặt"
 
@@ -955,7 +991,11 @@ msgstr ""
 msgid "Invalid"
 msgstr "Hợp lệ"
 
-#: src/views/preference/AuthSettings.vue:14
+#: src/views/other/Login.vue:83
+msgid "Invalid 2FA or recovery code"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:15
 msgid "IP"
 msgstr ""
 
@@ -1050,11 +1090,11 @@ msgstr "Locations"
 msgid "Log"
 msgstr "Log"
 
-#: src/routes/index.ts:279 src/views/other/Login.vue:159
+#: src/routes/index.ts:289 src/views/other/Login.vue:218
 msgid "Login"
 msgstr "Đăng nhập"
 
-#: src/views/other/Login.vue:109 src/views/other/Login.vue:51
+#: src/views/other/Login.vue:127 src/views/other/Login.vue:62
 msgid "Login successful"
 msgstr "Đăng nhập thành công"
 
@@ -1098,7 +1138,7 @@ msgstr "Quản lý Website"
 msgid "Manage Streams"
 msgstr "Quản lý Website"
 
-#: src/routes/index.ts:230 src/views/user/User.vue:50
+#: src/routes/index.ts:235 src/views/user/User.vue:50
 msgid "Manage Users"
 msgstr "Người dùng"
 
@@ -1106,7 +1146,7 @@ msgstr "Người dùng"
 msgid "Managed Certificate"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:74
+#: src/views/preference/AuthSettings.vue:75
 msgid "Max Attempts"
 msgstr ""
 
@@ -1240,7 +1280,7 @@ msgstr "Restart Nginx thành công"
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/domain/ngx_conf/LocationEditor.vue:71
 #: src/views/notification/Notification.vue:70
-#: src/views/preference/AuthSettings.vue:96
+#: src/views/preference/AuthSettings.vue:97
 #: src/views/preference/BasicSettings.vue:101
 #: src/views/stream/StreamList.vue:165
 msgid "No"
@@ -1254,7 +1294,7 @@ msgstr ""
 msgid "Not After"
 msgstr "Không phải sau khi"
 
-#: src/routes/index.ts:285
+#: src/routes/index.ts:295
 msgid "Not Found"
 msgstr "Không tìm thấy"
 
@@ -1272,7 +1312,7 @@ msgstr "Ghi chú"
 msgid "Notification"
 msgstr "Thông báo"
 
-#: src/components/Notification/Notification.vue:82 src/routes/index.ts:221
+#: src/components/Notification/Notification.vue:82 src/routes/index.ts:226
 #, fuzzy
 msgid "Notifications"
 msgstr "Thông báo"
@@ -1355,7 +1395,7 @@ msgstr "Ghi đè tập tin đã tồn tại"
 msgid "Params"
 msgstr "Tham số"
 
-#: src/views/other/Login.vue:144 src/views/user/User.vue:18
+#: src/views/other/Login.vue:167 src/views/user/User.vue:18
 msgid "Password"
 msgstr "Mật khẩu"
 
@@ -1381,6 +1421,10 @@ msgstr "Nâng cấp core không thành công"
 msgid "Performing core upgrade"
 msgstr "Nâng cấp core"
 
+#: src/views/other/Login.vue:177
+msgid "Please enter the 2FA code:"
+msgstr ""
+
 #: src/views/certificate/DNSCredential.vue:53
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
@@ -1412,11 +1456,11 @@ msgstr ""
 msgid "Please input your E-mail!"
 msgstr "Vui lòng nhập E-mail của bạn!"
 
-#: src/views/other/Install.vue:45 src/views/other/Login.vue:39
+#: src/views/other/Install.vue:45 src/views/other/Login.vue:45
 msgid "Please input your password!"
 msgstr "Vui lòng nhập mật khẩu!"
 
-#: src/views/other/Install.vue:39 src/views/other/Login.vue:33
+#: src/views/other/Install.vue:39 src/views/other/Login.vue:39
 msgid "Please input your username!"
 msgstr "Vui lòng nhập username!"
 
@@ -1436,7 +1480,7 @@ msgstr ""
 msgid "Pre-release"
 msgstr ""
 
-#: src/routes/index.ts:239 src/views/preference/Preference.vue:105
+#: src/routes/index.ts:244 src/views/preference/Preference.vue:105
 msgid "Preference"
 msgstr "Cài đặt"
 
@@ -1480,6 +1524,18 @@ msgstr ""
 msgid "Recovered Successfully"
 msgstr "Xoá thành công"
 
+#: src/views/other/Login.vue:204 src/views/preference/components/TOTP.vue:167
+msgid "Recovery"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:101
+msgid "Recovery Code"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:110
+msgid "Recovery Code:"
+msgstr ""
+
 #: src/views/preference/BasicSettings.vue:68
 msgid "Recursive Nameservers"
 msgstr ""
@@ -1534,11 +1590,11 @@ msgstr "Đang tải lại"
 msgid "Reloading nginx"
 msgstr "Tải lại nginx"
 
-#: src/views/preference/AuthSettings.vue:101
+#: src/views/preference/AuthSettings.vue:102
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:47
+#: src/views/preference/AuthSettings.vue:48
 #, fuzzy
 msgid "Remove successfully"
 msgstr "Xoá thành công"
@@ -1583,6 +1639,11 @@ msgstr "Yêu cầu có chứa tham số sai"
 msgid "Reset"
 msgstr "Đặt lại"
 
+#: src/views/preference/components/TOTP.vue:130
+#, fuzzy
+msgid "Reset 2FA"
+msgstr "Đặt lại"
+
 #: src/components/NginxControl/NginxControl.vue:93
 msgid "Restart"
 msgstr "Khởi động lại"
@@ -1632,6 +1693,10 @@ msgstr "Lưu thành công"
 msgid "Saved successfully"
 msgstr "Lưu thành công"
 
+#: src/views/preference/components/TOTP.vue:91
+msgid "Scan the QR code with your mobile phone to add the account to the app."
+msgstr ""
+
 #: src/views/certificate/DNSChallenge.vue:89
 msgid "SDK"
 msgstr ""
@@ -1655,7 +1720,9 @@ msgstr "Gửi"
 #: src/views/config/ConfigEdit.vue:40 src/views/domain/DomainList.vue:81
 #: src/views/environment/BatchUpgrader.vue:57
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:69
-#: src/views/preference/AuthSettings.vue:49
+#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/components/TOTP.vue:42
+#: src/views/preference/components/TOTP.vue:55
 #: src/views/preference/Preference.vue:78 src/views/stream/StreamList.vue:113
 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1729,7 +1796,7 @@ msgstr ""
 msgid "SSL Certificate Path"
 msgstr ""
 
-#: src/views/other/Login.vue:170
+#: src/views/other/Login.vue:229
 msgid "SSO Login"
 msgstr ""
 
@@ -1813,7 +1880,7 @@ msgstr "Gia hạn chứng chỉ SSL thành công"
 msgid "Sync to"
 msgstr ""
 
-#: src/routes/index.ts:248
+#: src/routes/index.ts:253
 msgid "System"
 msgstr "Thông tin"
 
@@ -1865,6 +1932,11 @@ msgstr ""
 msgid "The path exists, but the file is not a private key"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:109
+msgid ""
+"The recovery code is only displayed once, please save it in a safe place."
+msgstr ""
+
 #: src/views/dashboard/Environments.vue:148
 msgid ""
 "The remote Nginx UI version is not compatible with the local Nginx UI "
@@ -1923,7 +1995,7 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:59
+#: src/views/preference/AuthSettings.vue:60
 #: src/views/preference/LogrotateSettings.vue:12
 msgid "Tips"
 msgstr ""
@@ -1932,6 +2004,12 @@ msgstr ""
 msgid "Title"
 msgstr "Tiêu đề"
 
+#: src/views/preference/components/TOTP.vue:90
+msgid ""
+"To enable it, you need to install the Google or Microsoft Authenticator app "
+"on your mobile phone."
+msgstr ""
+
 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:44
 msgid ""
 "To make sure the certification auto-renewal can work normally, we need to "
@@ -1948,10 +2026,16 @@ msgstr ""
 msgid "Token is not valid"
 msgstr ""
 
-#: src/views/other/Login.vue:62
+#: src/views/other/Login.vue:76
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:89
+msgid ""
+"TOTP is a two-factor authentication method that uses a time-based one-time "
+"password algorithm."
+msgstr ""
+
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:209
 msgid "Trash"
 msgstr ""
@@ -1976,7 +2060,7 @@ msgstr "Ngày cập nhật"
 msgid "Updated successfully"
 msgstr "Cập nhật thành công"
 
-#: src/routes/index.ts:263 src/views/environment/Environment.vue:50
+#: src/routes/index.ts:268 src/views/environment/Environment.vue:50
 #: src/views/system/Upgrade.vue:145 src/views/system/Upgrade.vue:228
 msgid "Upgrade"
 msgstr "Cập nhật"
@@ -2007,16 +2091,20 @@ msgstr "Thời gian hoạt động:"
 msgid "URL"
 msgstr ""
 
+#: src/views/other/Login.vue:186
+msgid "Use recovery code"
+msgstr ""
+
 #: src/components/ChatGPT/ChatGPT.vue:229
 #, fuzzy
 msgid "User"
 msgstr "Người dùng"
 
-#: src/views/other/Login.vue:65
+#: src/views/other/Login.vue:79
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:134 src/views/user/User.vue:9
+#: src/views/other/Login.vue:157 src/views/user/User.vue:9
 msgid "Username"
 msgstr "Username"
 
@@ -2091,7 +2179,7 @@ msgstr "Ghi chứng chỉ vào disk"
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/domain/ngx_conf/LocationEditor.vue:70
-#: src/views/preference/AuthSettings.vue:95
+#: src/views/preference/AuthSettings.vue:96
 #: src/views/preference/BasicSettings.vue:100
 msgid "Yes"
 msgstr "Có"

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


+ 119 - 33
app/src/language/zh_CN/app.po

@@ -13,7 +13,11 @@ msgstr ""
 "Generated-By: easygettext\n"
 "X-Generator: Poedit 3.4.4\n"
 
-#: src/routes/index.ts:256
+#: src/views/preference/components/TOTP.vue:88
+msgid "2FA Settings"
+msgstr "2FA 设置"
+
+#: src/routes/index.ts:261
 msgid "About"
 msgstr "关于"
 
@@ -31,7 +35,7 @@ msgstr "ACME 用户"
 #: src/views/certificate/DNSCredential.vue:33 src/views/config/config.ts:34
 #: src/views/domain/DomainList.vue:47 src/views/environment/envColumns.tsx:131
 #: src/views/notification/Notification.vue:37
-#: src/views/preference/AuthSettings.vue:26 src/views/stream/StreamList.vue:47
+#: src/views/preference/AuthSettings.vue:27 src/views/stream/StreamList.vue:47
 #: src/views/user/User.vue:43
 msgid "Action"
 msgstr "操作"
@@ -95,7 +99,7 @@ msgstr "API Token"
 msgid "Arch"
 msgstr "架构"
 
-#: src/views/preference/AuthSettings.vue:94
+#: src/views/preference/AuthSettings.vue:95
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "您确定要立即删除这个被禁用的 IP 吗?"
 
@@ -144,7 +148,7 @@ msgstr "与ChatGPT聊天"
 msgid "Assistant"
 msgstr "助手"
 
-#: src/views/preference/AuthSettings.vue:17
+#: src/views/preference/AuthSettings.vue:18
 msgid "Attempts"
 msgstr "尝试次数"
 
@@ -188,15 +192,15 @@ msgstr "返回首页"
 msgid "Back to list"
 msgstr "返回列表"
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:69
 msgid "Ban Threshold Minutes"
 msgstr "禁止阈值(分钟)"
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:83
 msgid "Banned IPs"
 msgstr "禁止 IP 列表"
 
-#: src/views/preference/AuthSettings.vue:20
+#: src/views/preference/AuthSettings.vue:21
 msgid "Banned Until"
 msgstr "禁用至"
 
@@ -385,6 +389,14 @@ msgstr "DNS 凭证"
 msgid "Credentials"
 msgstr "凭证"
 
+#: src/views/preference/components/TOTP.vue:96
+msgid "Current account is enabled 2FA."
+msgstr "当前账户已启用二步验证。"
+
+#: src/views/preference/components/TOTP.vue:93
+msgid "Current account is not enabled 2FA."
+msgstr "当前用户未启用二步验证。"
+
 #: src/views/system/Upgrade.vue:167
 msgid "Current Version"
 msgstr "当前版本"
@@ -652,6 +664,14 @@ 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
+msgid "Enable 2FA"
+msgstr "启用二步验证"
+
+#: src/views/preference/components/TOTP.vue:52
+msgid "Enable 2FA successfully"
+msgstr "二步验证启用成功"
+
 #: src/views/domain/cert/components/ObtainCert.vue:70
 msgid "Enable auto-renewal failed for %{name}"
 msgstr "启用 %{name} 自动续签失败"
@@ -844,7 +864,7 @@ msgstr "HTTP01"
 msgid "If left blank, the default CA Dir will be used."
 msgstr "如果留空,则使用默认 CA Dir。"
 
-#: src/views/preference/AuthSettings.vue:60
+#: src/views/preference/AuthSettings.vue:61
 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."
@@ -852,6 +872,12 @@ msgstr ""
 "如果某个 IP 的登录失败次数达到禁用阈值分钟内的最大尝试次数,该 IP 将被禁止登"
 "录一段时间。"
 
+#: src/views/preference/components/TOTP.vue:108
+msgid ""
+"If you lose your mobile phone, you can use the recovery code to reset your "
+"2FA."
+msgstr "如果丢失了手机,可以使用恢复代码重置二步验证。"
+
 #: src/views/certificate/Certificate.vue:136
 msgid "Import"
 msgstr "导入"
@@ -860,7 +886,7 @@ msgstr "导入"
 msgid "Import Certificate"
 msgstr "导入证书"
 
-#: src/views/other/Login.vue:59
+#: src/views/other/Login.vue:73
 msgid "Incorrect username or password"
 msgstr "用户名或密码错误"
 
@@ -876,7 +902,15 @@ msgstr "初始化核心升级程序错误"
 msgid "Initialing core upgrader"
 msgstr "初始化核心升级器"
 
-#: src/routes/index.ts:273 src/views/other/Install.vue:135
+#: src/views/preference/components/TOTP.vue:144
+msgid "Input the code from the app:"
+msgstr "输入应用程序中的代码:"
+
+#: src/views/other/Login.vue:194 src/views/preference/components/TOTP.vue:157
+msgid "Input the recovery code:"
+msgstr "输入恢复代码:"
+
+#: src/routes/index.ts:283 src/views/other/Install.vue:135
 msgid "Install"
 msgstr "安装"
 
@@ -896,7 +930,11 @@ msgstr "间隔"
 msgid "Invalid"
 msgstr "无效的"
 
-#: src/views/preference/AuthSettings.vue:14
+#: src/views/other/Login.vue:83
+msgid "Invalid 2FA or recovery code"
+msgstr "无效的二步验证码或恢复密码"
+
+#: src/views/preference/AuthSettings.vue:15
 msgid "IP"
 msgstr "IP"
 
@@ -981,11 +1019,11 @@ msgstr "Locations"
 msgid "Log"
 msgstr "日志"
 
-#: src/routes/index.ts:279 src/views/other/Login.vue:159
+#: src/routes/index.ts:289 src/views/other/Login.vue:218
 msgid "Login"
 msgstr "登录"
 
-#: src/views/other/Login.vue:109 src/views/other/Login.vue:51
+#: src/views/other/Login.vue:127 src/views/other/Login.vue:62
 msgid "Login successful"
 msgstr "登录成功"
 
@@ -1031,7 +1069,7 @@ msgstr "网站管理"
 msgid "Manage Streams"
 msgstr "管理 Stream"
 
-#: src/routes/index.ts:230 src/views/user/User.vue:50
+#: src/routes/index.ts:235 src/views/user/User.vue:50
 msgid "Manage Users"
 msgstr "用户管理"
 
@@ -1039,7 +1077,7 @@ msgstr "用户管理"
 msgid "Managed Certificate"
 msgstr "托管证书"
 
-#: src/views/preference/AuthSettings.vue:74
+#: src/views/preference/AuthSettings.vue:75
 msgid "Max Attempts"
 msgstr "最大尝试次数"
 
@@ -1165,7 +1203,7 @@ msgstr "Nginx 重启成功"
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/domain/ngx_conf/LocationEditor.vue:71
 #: src/views/notification/Notification.vue:70
-#: src/views/preference/AuthSettings.vue:96
+#: src/views/preference/AuthSettings.vue:97
 #: src/views/preference/BasicSettings.vue:101
 #: src/views/stream/StreamList.vue:165
 msgid "No"
@@ -1179,7 +1217,7 @@ msgstr "节点密钥"
 msgid "Not After"
 msgstr "有效期"
 
-#: src/routes/index.ts:285
+#: src/routes/index.ts:295
 msgid "Not Found"
 msgstr "找不到页面"
 
@@ -1196,7 +1234,7 @@ msgstr "注意"
 msgid "Notification"
 msgstr "通知"
 
-#: src/components/Notification/Notification.vue:82 src/routes/index.ts:221
+#: src/components/Notification/Notification.vue:82 src/routes/index.ts:226
 msgid "Notifications"
 msgstr "通知"
 
@@ -1276,7 +1314,7 @@ msgstr "覆盖现有文件"
 msgid "Params"
 msgstr "参数"
 
-#: src/views/other/Login.vue:144 src/views/user/User.vue:18
+#: src/views/other/Login.vue:167 src/views/user/User.vue:18
 msgid "Password"
 msgstr "密码"
 
@@ -1302,6 +1340,10 @@ msgstr "执行核心升级错误"
 msgid "Performing core upgrade"
 msgstr "正在进行核心升级"
 
+#: src/views/other/Login.vue:177
+msgid "Please enter the 2FA code:"
+msgstr "请输入二步验证码:"
+
 #: src/views/certificate/DNSCredential.vue:53
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
@@ -1331,11 +1373,11 @@ msgstr "请输入名称,这将被用作新配置的文件名!"
 msgid "Please input your E-mail!"
 msgstr "请输入您的邮箱!"
 
-#: src/views/other/Install.vue:45 src/views/other/Login.vue:39
+#: src/views/other/Install.vue:45 src/views/other/Login.vue:45
 msgid "Please input your password!"
 msgstr "请输入您的密码!"
 
-#: src/views/other/Install.vue:39 src/views/other/Login.vue:33
+#: src/views/other/Install.vue:39 src/views/other/Login.vue:39
 msgid "Please input your username!"
 msgstr "请输入您的用户名!"
 
@@ -1355,7 +1397,7 @@ msgstr "请至少选择一个节点!"
 msgid "Pre-release"
 msgstr "预发布"
 
-#: src/routes/index.ts:239 src/views/preference/Preference.vue:105
+#: src/routes/index.ts:244 src/views/preference/Preference.vue:105
 msgid "Preference"
 msgstr "偏好设置"
 
@@ -1397,6 +1439,18 @@ msgstr "恢复"
 msgid "Recovered Successfully"
 msgstr "恢复成功"
 
+#: src/views/other/Login.vue:204 src/views/preference/components/TOTP.vue:167
+msgid "Recovery"
+msgstr "恢复"
+
+#: src/views/preference/components/TOTP.vue:101
+msgid "Recovery Code"
+msgstr "恢复代码"
+
+#: src/views/preference/components/TOTP.vue:110
+msgid "Recovery Code:"
+msgstr "恢复代码:"
+
 #: src/views/preference/BasicSettings.vue:68
 msgid "Recursive Nameservers"
 msgstr "递归域名服务器"
@@ -1446,11 +1500,11 @@ msgstr "重载中"
 msgid "Reloading nginx"
 msgstr "正在重载 Nginx"
 
-#: src/views/preference/AuthSettings.vue:101
+#: src/views/preference/AuthSettings.vue:102
 msgid "Remove"
 msgstr "删除"
 
-#: src/views/preference/AuthSettings.vue:47
+#: src/views/preference/AuthSettings.vue:48
 msgid "Remove successfully"
 msgstr "移除成功"
 
@@ -1488,6 +1542,10 @@ msgstr "请求参数错误"
 msgid "Reset"
 msgstr "重置"
 
+#: src/views/preference/components/TOTP.vue:130
+msgid "Reset 2FA"
+msgstr "重置二步验证"
+
 #: src/components/NginxControl/NginxControl.vue:93
 msgid "Restart"
 msgstr "重启"
@@ -1535,6 +1593,10 @@ msgstr "保存成功"
 msgid "Saved successfully"
 msgstr "保存成功"
 
+#: src/views/preference/components/TOTP.vue:91
+msgid "Scan the QR code with your mobile phone to add the account to the app."
+msgstr "用手机扫描二维码,将账户添加到应用程序中。"
+
 #: src/views/certificate/DNSChallenge.vue:89
 msgid "SDK"
 msgstr "SDK"
@@ -1558,7 +1620,9 @@ msgstr "上传"
 #: src/views/config/ConfigEdit.vue:40 src/views/domain/DomainList.vue:81
 #: src/views/environment/BatchUpgrader.vue:57
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:69
-#: src/views/preference/AuthSettings.vue:49
+#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/components/TOTP.vue:42
+#: src/views/preference/components/TOTP.vue:55
 #: src/views/preference/Preference.vue:78 src/views/stream/StreamList.vue:113
 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1629,7 +1693,7 @@ msgstr "SSL证书密钥路径"
 msgid "SSL Certificate Path"
 msgstr "SSL证书路径"
 
-#: src/views/other/Login.vue:170
+#: src/views/other/Login.vue:229
 msgid "SSO Login"
 msgstr "SSO 登录"
 
@@ -1707,7 +1771,7 @@ msgstr "同步证书成功"
 msgid "Sync to"
 msgstr "同步到"
 
-#: src/routes/index.ts:248
+#: src/routes/index.ts:253
 msgid "System"
 msgstr "系统"
 
@@ -1758,6 +1822,11 @@ msgstr "路径存在,但文件不是证书"
 msgid "The path exists, but the file is not a private key"
 msgstr "路径存在,但文件不是私钥"
 
+#: src/views/preference/components/TOTP.vue:109
+msgid ""
+"The recovery code is only displayed once, please save it in a safe place."
+msgstr "恢复密码只会显示一次,请妥善保存。"
+
 #: src/views/dashboard/Environments.vue:148
 msgid ""
 "The remote Nginx UI version is not compatible with the local Nginx UI "
@@ -1816,7 +1885,7 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr "将 %{nodeNames} 上的 Nginx UI 升级或重新安装到 %{version} 版本。"
 
-#: src/views/preference/AuthSettings.vue:59
+#: src/views/preference/AuthSettings.vue:60
 #: src/views/preference/LogrotateSettings.vue:12
 msgid "Tips"
 msgstr "提示"
@@ -1825,6 +1894,13 @@ msgstr "提示"
 msgid "Title"
 msgstr "标题"
 
+#: src/views/preference/components/TOTP.vue:90
+msgid ""
+"To enable it, you need to install the Google or Microsoft Authenticator app "
+"on your mobile phone."
+msgstr ""
+"要启用该功能,您需要在手机上安装 Google 或 Microsoft Authenticator 应用程序。"
+
 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:44
 msgid ""
 "To make sure the certification auto-renewal can work normally, we need to "
@@ -1839,10 +1915,16 @@ msgstr ""
 msgid "Token is not valid"
 msgstr "Token 无效"
 
-#: src/views/other/Login.vue:62
+#: src/views/other/Login.vue:76
 msgid "Too many login failed attempts, please try again later"
 msgstr "登录失败次数过多,请稍后再试"
 
+#: src/views/preference/components/TOTP.vue:89
+msgid ""
+"TOTP is a two-factor authentication method that uses a time-based one-time "
+"password algorithm."
+msgstr "TOTP 是一种使用基于时间的一次性密码算法的双因素身份验证方法。"
+
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:209
 msgid "Trash"
 msgstr "回收站"
@@ -1866,7 +1948,7 @@ msgstr "修改时间"
 msgid "Updated successfully"
 msgstr "更新成功"
 
-#: src/routes/index.ts:263 src/views/environment/Environment.vue:50
+#: src/routes/index.ts:268 src/views/environment/Environment.vue:50
 #: src/views/system/Upgrade.vue:145 src/views/system/Upgrade.vue:228
 msgid "Upgrade"
 msgstr "升级"
@@ -1895,15 +1977,19 @@ msgstr "运行时间:"
 msgid "URL"
 msgstr "URL"
 
+#: src/views/other/Login.vue:186
+msgid "Use recovery code"
+msgstr "使用恢复代码"
+
 #: src/components/ChatGPT/ChatGPT.vue:229
 msgid "User"
 msgstr "用户"
 
-#: src/views/other/Login.vue:65
+#: src/views/other/Login.vue:79
 msgid "User is banned"
 msgstr "用户被禁止"
 
-#: src/views/other/Login.vue:134 src/views/user/User.vue:9
+#: src/views/other/Login.vue:157 src/views/user/User.vue:9
 msgid "Username"
 msgstr "用户名"
 
@@ -1971,7 +2057,7 @@ msgstr "正在将证书写入磁盘"
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/domain/ngx_conf/LocationEditor.vue:70
-#: src/views/preference/AuthSettings.vue:95
+#: src/views/preference/AuthSettings.vue:96
 #: src/views/preference/BasicSettings.vue:100
 msgid "Yes"
 msgstr "是的"

+ 121 - 33
app/src/language/zh_TW/app.po

@@ -14,7 +14,11 @@ msgstr ""
 "Generated-By: easygettext\n"
 "X-Generator: Poedit 3.4.1\n"
 
-#: src/routes/index.ts:256
+#: src/views/preference/components/TOTP.vue:88
+msgid "2FA Settings"
+msgstr ""
+
+#: src/routes/index.ts:261
 msgid "About"
 msgstr "關於"
 
@@ -33,7 +37,7 @@ msgstr "使用者名稱"
 #: src/views/certificate/DNSCredential.vue:33 src/views/config/config.ts:34
 #: src/views/domain/DomainList.vue:47 src/views/environment/envColumns.tsx:131
 #: src/views/notification/Notification.vue:37
-#: src/views/preference/AuthSettings.vue:26 src/views/stream/StreamList.vue:47
+#: src/views/preference/AuthSettings.vue:27 src/views/stream/StreamList.vue:47
 #: src/views/user/User.vue:43
 msgid "Action"
 msgstr "操作"
@@ -100,7 +104,7 @@ msgstr "API Token"
 msgid "Arch"
 msgstr "架構"
 
-#: src/views/preference/AuthSettings.vue:94
+#: src/views/preference/AuthSettings.vue:95
 #, fuzzy
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "您確定要刪除嗎?"
@@ -155,7 +159,7 @@ msgstr "向 ChatGPT 尋求幫助"
 msgid "Assistant"
 msgstr "助理"
 
-#: src/views/preference/AuthSettings.vue:17
+#: src/views/preference/AuthSettings.vue:18
 msgid "Attempts"
 msgstr ""
 
@@ -200,15 +204,15 @@ msgstr "返回首頁"
 msgid "Back to list"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:69
 msgid "Ban Threshold Minutes"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:83
 msgid "Banned IPs"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:20
+#: src/views/preference/AuthSettings.vue:21
 msgid "Banned Until"
 msgstr ""
 
@@ -404,6 +408,14 @@ msgstr "認證"
 msgid "Credentials"
 msgstr "認證資訊"
 
+#: src/views/preference/components/TOTP.vue:96
+msgid "Current account is enabled 2FA."
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:93
+msgid "Current account is not enabled 2FA."
+msgstr ""
+
 #: src/views/system/Upgrade.vue:167
 msgid "Current Version"
 msgstr "目前版本"
@@ -680,6 +692,16 @@ 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
+#, fuzzy
+msgid "Enable 2FA"
+msgstr "啟用"
+
+#: src/views/preference/components/TOTP.vue:52
+#, fuzzy
+msgid "Enable 2FA successfully"
+msgstr "啟用成功"
+
 #: src/views/domain/cert/components/ObtainCert.vue:70
 msgid "Enable auto-renewal failed for %{name}"
 msgstr "啟用 %{name} 自動續簽失敗"
@@ -878,12 +900,18 @@ msgstr "HTTP01"
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:60
+#: src/views/preference/AuthSettings.vue:61
 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
+msgid ""
+"If you lose your mobile phone, you can use the recovery code to reset your "
+"2FA."
+msgstr ""
+
 #: src/views/certificate/Certificate.vue:136
 #, fuzzy
 msgid "Import"
@@ -894,7 +922,7 @@ msgstr "匯出"
 msgid "Import Certificate"
 msgstr "憑證狀態"
 
-#: src/views/other/Login.vue:59
+#: src/views/other/Login.vue:73
 #, fuzzy
 msgid "Incorrect username or password"
 msgstr "使用者名稱或密碼不正確"
@@ -911,7 +939,15 @@ msgstr "初始化核心升級程式錯誤"
 msgid "Initialing core upgrader"
 msgstr "正在初始化核心升級程式"
 
-#: src/routes/index.ts:273 src/views/other/Install.vue:135
+#: src/views/preference/components/TOTP.vue:144
+msgid "Input the code from the app:"
+msgstr ""
+
+#: src/views/other/Login.vue:194 src/views/preference/components/TOTP.vue:157
+msgid "Input the recovery code:"
+msgstr ""
+
+#: src/routes/index.ts:283 src/views/other/Install.vue:135
 msgid "Install"
 msgstr "安裝"
 
@@ -932,7 +968,11 @@ msgstr ""
 msgid "Invalid"
 msgstr "無效的郵箱!"
 
-#: src/views/preference/AuthSettings.vue:14
+#: src/views/other/Login.vue:83
+msgid "Invalid 2FA or recovery code"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:15
 msgid "IP"
 msgstr ""
 
@@ -1025,11 +1065,11 @@ msgstr "Locations"
 msgid "Log"
 msgstr "登入"
 
-#: src/routes/index.ts:279 src/views/other/Login.vue:159
+#: src/routes/index.ts:289 src/views/other/Login.vue:218
 msgid "Login"
 msgstr "登入"
 
-#: src/views/other/Login.vue:109 src/views/other/Login.vue:51
+#: src/views/other/Login.vue:127 src/views/other/Login.vue:62
 msgid "Login successful"
 msgstr "登入成功"
 
@@ -1071,7 +1111,7 @@ msgstr "管理網站"
 msgid "Manage Streams"
 msgstr "管理網站"
 
-#: src/routes/index.ts:230 src/views/user/User.vue:50
+#: src/routes/index.ts:235 src/views/user/User.vue:50
 msgid "Manage Users"
 msgstr "管理使用者"
 
@@ -1080,7 +1120,7 @@ msgstr "管理使用者"
 msgid "Managed Certificate"
 msgstr "更換憑證"
 
-#: src/views/preference/AuthSettings.vue:74
+#: src/views/preference/AuthSettings.vue:75
 msgid "Max Attempts"
 msgstr ""
 
@@ -1209,7 +1249,7 @@ msgstr "Nginx 重啟成功"
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/domain/ngx_conf/LocationEditor.vue:71
 #: src/views/notification/Notification.vue:70
-#: src/views/preference/AuthSettings.vue:96
+#: src/views/preference/AuthSettings.vue:97
 #: src/views/preference/BasicSettings.vue:101
 #: src/views/stream/StreamList.vue:165
 msgid "No"
@@ -1223,7 +1263,7 @@ msgstr "Node Secret"
 msgid "Not After"
 msgstr ""
 
-#: src/routes/index.ts:285
+#: src/routes/index.ts:295
 msgid "Not Found"
 msgstr "找不到頁面"
 
@@ -1241,7 +1281,7 @@ msgstr "備註"
 msgid "Notification"
 msgstr "憑證"
 
-#: src/components/Notification/Notification.vue:82 src/routes/index.ts:221
+#: src/components/Notification/Notification.vue:82 src/routes/index.ts:226
 #, fuzzy
 msgid "Notifications"
 msgstr "憑證"
@@ -1322,7 +1362,7 @@ msgstr "覆蓋現有檔案"
 msgid "Params"
 msgstr "參數"
 
-#: src/views/other/Login.vue:144 src/views/user/User.vue:18
+#: src/views/other/Login.vue:167 src/views/user/User.vue:18
 msgid "Password"
 msgstr "密碼"
 
@@ -1348,6 +1388,10 @@ msgstr "執行核心升級錯誤"
 msgid "Performing core upgrade"
 msgstr "正在執行核心升級"
 
+#: src/views/other/Login.vue:177
+msgid "Please enter the 2FA code:"
+msgstr ""
+
 #: src/views/certificate/DNSCredential.vue:53
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
@@ -1378,11 +1422,11 @@ msgstr "請輸入名稱,這將作為新設定的檔名!"
 msgid "Please input your E-mail!"
 msgstr "請輸入您的電子郵件!"
 
-#: src/views/other/Install.vue:45 src/views/other/Login.vue:39
+#: src/views/other/Install.vue:45 src/views/other/Login.vue:45
 msgid "Please input your password!"
 msgstr "請輸入您的密碼!"
 
-#: src/views/other/Install.vue:39 src/views/other/Login.vue:33
+#: src/views/other/Install.vue:39 src/views/other/Login.vue:39
 msgid "Please input your username!"
 msgstr "請輸入您的使用者名稱!"
 
@@ -1402,7 +1446,7 @@ msgstr "請至少選擇一個節點!"
 msgid "Pre-release"
 msgstr "預先發布"
 
-#: src/routes/index.ts:239 src/views/preference/Preference.vue:105
+#: src/routes/index.ts:244 src/views/preference/Preference.vue:105
 msgid "Preference"
 msgstr "偏好設定"
 
@@ -1445,6 +1489,18 @@ msgstr ""
 msgid "Recovered Successfully"
 msgstr "儲存成功"
 
+#: src/views/other/Login.vue:204 src/views/preference/components/TOTP.vue:167
+msgid "Recovery"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:101
+msgid "Recovery Code"
+msgstr ""
+
+#: src/views/preference/components/TOTP.vue:110
+msgid "Recovery Code:"
+msgstr ""
+
 #: src/views/preference/BasicSettings.vue:68
 #, fuzzy
 msgid "Recursive Nameservers"
@@ -1499,11 +1555,11 @@ msgstr "重新載入中"
 msgid "Reloading nginx"
 msgstr "正在重新載入 Nginx"
 
-#: src/views/preference/AuthSettings.vue:101
+#: src/views/preference/AuthSettings.vue:102
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:47
+#: src/views/preference/AuthSettings.vue:48
 #, fuzzy
 msgid "Remove successfully"
 msgstr "儲存成功"
@@ -1548,6 +1604,11 @@ msgstr "請求參數錯誤"
 msgid "Reset"
 msgstr "重設"
 
+#: src/views/preference/components/TOTP.vue:130
+#, fuzzy
+msgid "Reset 2FA"
+msgstr "重設"
+
 #: src/components/NginxControl/NginxControl.vue:93
 msgid "Restart"
 msgstr "重新啟動"
@@ -1595,6 +1656,10 @@ msgstr "儲存成功"
 msgid "Saved successfully"
 msgstr "儲存成功"
 
+#: src/views/preference/components/TOTP.vue:91
+msgid "Scan the QR code with your mobile phone to add the account to the app."
+msgstr ""
+
 #: src/views/certificate/DNSChallenge.vue:89
 msgid "SDK"
 msgstr ""
@@ -1618,7 +1683,9 @@ msgstr "傳送"
 #: src/views/config/ConfigEdit.vue:40 src/views/domain/DomainList.vue:81
 #: src/views/environment/BatchUpgrader.vue:57
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:69
-#: src/views/preference/AuthSettings.vue:49
+#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/components/TOTP.vue:42
+#: src/views/preference/components/TOTP.vue:55
 #: src/views/preference/Preference.vue:78 src/views/stream/StreamList.vue:113
 #: src/views/stream/StreamList.vue:81 src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1694,7 +1761,7 @@ msgstr "SSL 憑證金鑰路徑"
 msgid "SSL Certificate Path"
 msgstr "SSL 憑證路徑"
 
-#: src/views/other/Login.vue:170
+#: src/views/other/Login.vue:229
 #, fuzzy
 msgid "SSO Login"
 msgstr "登入"
@@ -1778,7 +1845,7 @@ msgstr "更換憑證"
 msgid "Sync to"
 msgstr ""
 
-#: src/routes/index.ts:248
+#: src/routes/index.ts:253
 msgid "System"
 msgstr "系統"
 
@@ -1832,6 +1899,11 @@ msgstr "SSL 憑證金鑰路徑"
 msgid "The path exists, but the file is not a private key"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:109
+msgid ""
+"The recovery code is only displayed once, please save it in a safe place."
+msgstr ""
+
 #: src/views/dashboard/Environments.vue:148
 msgid ""
 "The remote Nginx UI version is not compatible with the local Nginx UI "
@@ -1892,7 +1964,7 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:59
+#: src/views/preference/AuthSettings.vue:60
 #: src/views/preference/LogrotateSettings.vue:12
 msgid "Tips"
 msgstr ""
@@ -1901,6 +1973,12 @@ msgstr ""
 msgid "Title"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:90
+msgid ""
+"To enable it, you need to install the Google or Microsoft Authenticator app "
+"on your mobile phone."
+msgstr ""
+
 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:44
 msgid ""
 "To make sure the certification auto-renewal can work normally, we need to "
@@ -1915,10 +1993,16 @@ msgstr ""
 msgid "Token is not valid"
 msgstr ""
 
-#: src/views/other/Login.vue:62
+#: src/views/other/Login.vue:76
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
+#: src/views/preference/components/TOTP.vue:89
+msgid ""
+"TOTP is a two-factor authentication method that uses a time-based one-time "
+"password algorithm."
+msgstr ""
+
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:209
 msgid "Trash"
 msgstr ""
@@ -1942,7 +2026,7 @@ msgstr "更新時間"
 msgid "Updated successfully"
 msgstr "更新成功"
 
-#: src/routes/index.ts:263 src/views/environment/Environment.vue:50
+#: src/routes/index.ts:268 src/views/environment/Environment.vue:50
 #: src/views/system/Upgrade.vue:145 src/views/system/Upgrade.vue:228
 msgid "Upgrade"
 msgstr "升級"
@@ -1972,15 +2056,19 @@ msgstr "運作時間:"
 msgid "URL"
 msgstr "URL"
 
+#: src/views/other/Login.vue:186
+msgid "Use recovery code"
+msgstr ""
+
 #: src/components/ChatGPT/ChatGPT.vue:229
 msgid "User"
 msgstr "使用者名稱"
 
-#: src/views/other/Login.vue:65
+#: src/views/other/Login.vue:79
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:134 src/views/user/User.vue:9
+#: src/views/other/Login.vue:157 src/views/user/User.vue:9
 msgid "Username"
 msgstr "使用者名稱"
 
@@ -2052,7 +2140,7 @@ msgstr "將憑證寫入磁碟"
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/domain/ngx_conf/LocationEditor.vue:70
-#: src/views/preference/AuthSettings.vue:95
+#: src/views/preference/AuthSettings.vue:96
 #: src/views/preference/BasicSettings.vue:100
 msgid "Yes"
 msgstr "是的"