diff --git a/lib/l10n/arb/app_it.arb b/lib/l10n/arb/app_it.arb index 944e7280c..324c48a25 100644 --- a/lib/l10n/arb/app_it.arb +++ b/lib/l10n/arb/app_it.arb @@ -12,6 +12,10 @@ "qrCode": "Codice QR", "importEnterSetupKey": "Inserisci il codice segreto", "importAccountPageTitle": "Inserisci i dettagli del tuo account", + "secretCanNotBeEmpty": "La chiave segreta è obbligatoria", + "bothIssuerAndAccountCanNotBeEmpty": "Sia l'emittente che l'account sono obbligatori", + "incorrectDetails": "Dettagli errati", + "pleaseVerifyDetails": "Verifica i dettagli e riprova", "codeIssuerHint": "Emittente", "codeSecretKeyHint": "Codice segreto", "codeAccountHint": "Account (username@dominio.it)", @@ -69,13 +73,22 @@ "changePassword": "Cambia password", "data": "Dati", "importCodes": "Importa codici", + "importTypePlainText": "Testo in chiaro", + "importTypeEnteEncrypted": "ente Esportazione criptata", + "passwordForDecryptingExport": "Password per decriptare il file esportato", + "passwordEmptyError": "La password è obbligatoria", + "importFromApp": "Importa codici da {appName}", + "importGoogleAuthGuide": "Esporta i tuoi account da Google Authenticator in un codice QR utilizzando l'opzione \"Trasferisci Account\". Quindi, usando un altro dispositivo, scansiona il codice QR.\n\nSuggerimento: Puoi usare la webcam del tuo computer portatile per scattare una foto del codice QR.", "importSelectJsonFile": "Seleziona file JSON", + "importEnteEncGuide": "Seleziona il file JSON criptato esportato da ente", + "importRaivoGuide": "Utilizza l'opzione \"Esporta i codici OTP in archivio Zip\" nelle impostazioni di Raivo.\n\nEstrai il file zip e importa il file JSON.", "exportCodes": "Esporta codici", "importLabel": "Importa", "importInstruction": "Per favore seleziona un file contenente una lista dei tuoi codici nel seguente formato", "importCodeDelimiterInfo": "I codici possono essere separati da una virgola o da una nuova riga", "selectFile": "Seleziona file", "emailVerificationToggle": "Verifica Email", + "authToChangeEmailVerificationSetting": "Autenticati per cambiare la verifica email", "authToViewYourRecoveryKey": "Autenticati per visualizzare la tua chiave di recupero", "authToChangeYourEmail": "Autenticati per cambiare la tua email", "authToChangeYourPassword": "Autenticati per cambiare la tua password", @@ -94,9 +107,18 @@ "enterYourPasswordHint": "Inserisci la tua password", "forgotPassword": "Password dimenticata", "oops": "Oops", + "suggestFeatures": "Suggerisci funzionalità", "faq": "FAQ", + "faq_q_1": "Quanto è sicuro ente Auth?", + "faq_a_1": "Tutti i codici di cui fai il backup tramite ente sono memorizzati con crittografia end-to-end. Ciò significa che solo tu puoi accedere ai tuoi codici. Le nostre app sono open source e la nostra crittografia è stata verificata esternamente.", + "faq_q_2": "Posso accedere ai miei codici sul desktop?", + "faq_a_2": "Puoi accedere ai tuoi codici sul web @ auth.ente.io.", "faq_q_3": "Come posso cancellare i codici?", + "faq_a_3": "Puoi eliminare un codice scorrendo il dito a sinistra sul codice in questione.", "faq_q_4": "Come posso supportare questo progetto?", + "faq_a_4": "Puoi supportare lo sviluppo di questo progetto abbonandoti alla nostra app Photos @ ente.io.", + "faq_q_5": "Come posso abilitare il blocco FaceID in ente Auth", + "faq_a_5": "Puoi abilitare il blocco FaceID in Impostazioni → Sicurezza → Schermata di blocco.", "somethingWentWrongMessage": "Qualcosa è andato storto, per favore riprova", "leaveFamily": "Abbandona il piano famiglia", "leaveFamilyMessage": "Sei sicuro di voler uscire dal piano famiglia?", @@ -274,6 +296,15 @@ "thisDevice": "Questo dispositivo", "toResetVerifyEmail": "Per reimpostare la tua password, prima verifica la tua email.", "thisEmailIsAlreadyInUse": "Questa email é già in uso", + "verificationFailedPleaseTryAgain": "Verifica fallita, per favore riprova", + "yourVerificationCodeHasExpired": "Il tuo codice di verifica è scaduto", "incorrectCode": "Codice errato", + "sorryTheCodeYouveEnteredIsIncorrect": "Spiacenti, il codice che hai inserito non è corretto", + "emailChangedTo": "Email modificata in {newEmail}", + "authenticationFailedPleaseTryAgain": "Autenticazione non riuscita, riprova", + "authenticationSuccessful": "Autenticazione riuscita!", + "twofactorAuthenticationSuccessfullyReset": "Autenticazione a due fattori ripristinata con successo", + "incorrectRecoveryKey": "Chiave di recupero errata", + "theRecoveryKeyYouEnteredIsIncorrect": "La chiave di recupero che hai inserito non è corretta", "enterPassword": "Inserisci la password" } \ No newline at end of file diff --git a/lib/onboarding/view/setup_enter_secret_key_page.dart b/lib/onboarding/view/setup_enter_secret_key_page.dart index 4d0aab9ec..5a72f9cb4 100644 --- a/lib/onboarding/view/setup_enter_secret_key_page.dart +++ b/lib/onboarding/view/setup_enter_secret_key_page.dart @@ -23,12 +23,12 @@ class _SetupEnterSecretKeyPageState extends State { void initState() { _issuerController = TextEditingController( text: widget.code != null - ? Uri.decodeFull(widget.code!.issuer).trim() + ? safeDecode(widget.code!.issuer).trim() : null, ); _accountController = TextEditingController( text: widget.code != null - ? Uri.decodeFull(widget.code!.account).trim() + ? safeDecode(widget.code!.account).trim() : null, ); _secretController = TextEditingController( diff --git a/lib/ui/code_widget.dart b/lib/ui/code_widget.dart index 09b81f559..85f78b05b 100644 --- a/lib/ui/code_widget.dart +++ b/lib/ui/code_widget.dart @@ -306,15 +306,6 @@ class _CodeWidgetState extends State { ); } - String safeDecode(String value) { - try { - return Uri.decodeComponent(value); - } catch (e) { - // note: don't log the value, it might contain sensitive information - logger.severe("Failed to decode", e); - return value; - } - } String _getCurrentOTP() { try { diff --git a/lib/utils/totp_util.dart b/lib/utils/totp_util.dart index d76318280..a49448524 100644 --- a/lib/utils/totp_util.dart +++ b/lib/utils/totp_util.dart @@ -1,4 +1,5 @@ import 'package:ente_auth/models/code.dart'; +import 'package:flutter/foundation.dart'; import 'package:otp/otp.dart' as otp; String getOTP(Code code) { @@ -50,3 +51,13 @@ otp.Algorithm _getAlgorithm(Code code) { String getSanitizedSecret(String secret) { return secret.toUpperCase().trim().replaceAll(' ', ''); } + +String safeDecode(String value) { + try { + return Uri.decodeComponent(value); + } catch (e) { + // note: don't log the value, it might contain sensitive information + debugPrint("Failed to decode $e"); + return value; + } +} \ No newline at end of file diff --git a/test/models/code_test.dart b/test/models/code_test.dart index 9a0d18e03..30ea23a4f 100644 --- a/test/models/code_test.dart +++ b/test/models/code_test.dart @@ -39,4 +39,16 @@ void main() { expect(code.account, "Acc !@#444", reason: "accountMismatch"); expect(code.secret, "NI4CTTFEV4G2JFE6"); }); + + test("parseAndUpdateInChinese", () { + const String rubberDuckQr = + 'otpauth://totp/%E6%A9%A1%E7%9A%AE%E9%B8%AD?secret=2CWDCK4EOIN5DJDRMYUMYBBO4MKSR5AX&issuer=ente.io'; + final code = Code.fromRawData(rubberDuckQr); + expect(code.account, '橡皮鸭'); + final String updatedRawCode = + code.copyWith(account: '伍迪', issuer: '鸭子').rawData; + final updateCode = Code.fromRawData(updatedRawCode); + expect(updateCode.account, '伍迪', reason: 'updated accountMismatch'); + expect(updateCode.issuer, '鸭子', reason: 'updated issuerMismatch'); + }); }