diff --git a/app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java b/app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java index 8138acf1..cbf43193 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java +++ b/app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java @@ -9,6 +9,7 @@ import com.beemdevelopment.aegis.encoding.Base32; import com.beemdevelopment.aegis.encoding.Base64; import com.beemdevelopment.aegis.encoding.EncodingException; import com.beemdevelopment.aegis.encoding.Hex; +import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import java.io.Serializable; @@ -18,7 +19,7 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; -public class GoogleAuthInfo implements Serializable { +public class GoogleAuthInfo implements Transferable, Serializable { public static final String SCHEME = "otpauth"; public static final String SCHEME_EXPORT = "otpauth-migration"; @@ -267,6 +268,7 @@ public class GoogleAuthInfo implements Serializable { return _info; } + @Override public Uri getUri() { Uri.Builder builder = new Uri.Builder(); @@ -319,7 +321,7 @@ public class GoogleAuthInfo implements Serializable { return _accountName; } - public static class Export { + public static class Export implements Transferable, Serializable { private int _batchId; private int _batchIndex; private int _batchSize; @@ -385,5 +387,72 @@ public class GoogleAuthInfo implements Serializable { return true; } + + @Override + public Uri getUri() throws GoogleAuthInfoException { + GoogleAuthProtos.MigrationPayload.Builder builder = GoogleAuthProtos.MigrationPayload.newBuilder(); + builder.setBatchId(_batchId) + .setBatchIndex(_batchIndex) + .setBatchSize(_batchSize) + .setVersion(1); + + for (GoogleAuthInfo info: _entries) { + GoogleAuthProtos.MigrationPayload.OtpParameters.Builder parameters = GoogleAuthProtos.MigrationPayload.OtpParameters.newBuilder() + .setSecret(ByteString.copyFrom(info.getOtpInfo().getSecret())) + .setName(info.getAccountName()) + .setIssuer(info.getIssuer()); + + switch (info.getOtpInfo().getAlgorithm(false)) { + case "SHA1": + parameters.setAlgorithm(GoogleAuthProtos.MigrationPayload.Algorithm.ALGORITHM_SHA1); + break; + case "SHA256": + parameters.setAlgorithm(GoogleAuthProtos.MigrationPayload.Algorithm.ALGORITHM_SHA256); + break; + case "SHA512": + parameters.setAlgorithm(GoogleAuthProtos.MigrationPayload.Algorithm.ALGORITHM_SHA512); + break; + case "MD5": + parameters.setAlgorithm(GoogleAuthProtos.MigrationPayload.Algorithm.ALGORITHM_MD5); + break; + default: + throw new GoogleAuthInfoException(info.getUri(), String.format("Unsupported Algorithm: %s", info.getOtpInfo().getAlgorithm(false))); + } + + switch (info.getOtpInfo().getDigits()) { + case 6: + parameters.setDigits(GoogleAuthProtos.MigrationPayload.DigitCount.DIGIT_COUNT_SIX); + break; + case 8: + parameters.setDigits(GoogleAuthProtos.MigrationPayload.DigitCount.DIGIT_COUNT_EIGHT); + break; + default: + throw new GoogleAuthInfoException(info.getUri(), String.format("Unsupported number of digits: %s", info.getOtpInfo().getDigits())); + } + + switch (info.getOtpInfo().getType().toLowerCase()) { + case HotpInfo.ID: + parameters.setType(GoogleAuthProtos.MigrationPayload.OtpType.OTP_TYPE_HOTP); + parameters.setCounter(((HotpInfo) info.getOtpInfo()).getCounter()); + break; + case TotpInfo.ID: + parameters.setType(GoogleAuthProtos.MigrationPayload.OtpType.OTP_TYPE_TOTP); + break; + default: + throw new GoogleAuthInfoException(info.getUri(), String.format("Type unsupported by GoogleAuthProtos: %s", info.getOtpInfo().getType())); + } + + builder.addOtpParameters(parameters.build()); + } + + Uri.Builder exportUriBuilder = new Uri.Builder() + .scheme(SCHEME_EXPORT) + .authority("offline"); + + String data = Base64.encode(builder.build().toByteArray()); + exportUriBuilder.appendQueryParameter("data", data); + + return exportUriBuilder.build(); + } } } diff --git a/app/src/main/java/com/beemdevelopment/aegis/otp/Transferable.java b/app/src/main/java/com/beemdevelopment/aegis/otp/Transferable.java new file mode 100644 index 00000000..475db077 --- /dev/null +++ b/app/src/main/java/com/beemdevelopment/aegis/otp/Transferable.java @@ -0,0 +1,7 @@ +package com.beemdevelopment.aegis.otp; + +import android.net.Uri; + +public interface Transferable { + Uri getUri() throws GoogleAuthInfoException; +} diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/TransferEntriesActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/TransferEntriesActivity.java index f4350153..756ce1ee 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/TransferEntriesActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/TransferEntriesActivity.java @@ -17,6 +17,8 @@ import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.Theme; import com.beemdevelopment.aegis.helpers.QrCodeHelper; import com.beemdevelopment.aegis.otp.GoogleAuthInfo; +import com.beemdevelopment.aegis.otp.GoogleAuthInfoException; +import com.beemdevelopment.aegis.otp.Transferable; import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.google.zxing.WriterException; @@ -24,8 +26,9 @@ import java.util.ArrayList; import java.util.List; public class TransferEntriesActivity extends AegisActivity { - private List _authInfos; + private List _authInfos; private ImageView _qrImage; + private TextView _description; private TextView _issuer; private TextView _accountName; private TextView _entriesCount; @@ -43,6 +46,7 @@ public class TransferEntriesActivity extends AegisActivity { setSupportActionBar(findViewById(R.id.toolbar)); _qrImage = findViewById(R.id.ivQrCode); + _description = findViewById(R.id.tvDescription); _issuer = findViewById(R.id.tvIssuer); _accountName = findViewById(R.id.tvAccountName); _entriesCount = findViewById(R.id.tvEntriesCount); @@ -55,7 +59,7 @@ public class TransferEntriesActivity extends AegisActivity { } Intent intent = getIntent(); - _authInfos = (ArrayList) intent.getSerializableExtra("authInfos"); + _authInfos = (ArrayList) intent.getSerializableExtra("authInfos"); int controlVisibility = _authInfos.size() != 1 ? View.VISIBLE : View.INVISIBLE; _nextButton.setVisibility(controlVisibility); @@ -103,10 +107,16 @@ public class TransferEntriesActivity extends AegisActivity { } private void generateQR() { - GoogleAuthInfo selectedEntry = _authInfos.get(_currentEntryCount - 1); - _issuer.setText(selectedEntry.getIssuer()); - _accountName.setText(selectedEntry.getAccountName()); - _entriesCount.setText(getResources().getQuantityString(R.plurals.entries_count, _authInfos.size(), _currentEntryCount, _authInfos.size())); + Transferable selectedEntry = _authInfos.get(_currentEntryCount - 1); + if (selectedEntry instanceof GoogleAuthInfo) { + GoogleAuthInfo entry = (GoogleAuthInfo) selectedEntry; + _issuer.setText(entry.getIssuer()); + _accountName.setText(entry.getAccountName()); + } else if (selectedEntry instanceof GoogleAuthInfo.Export) { + _description.setText(R.string.google_auth_compatible_transfer_description); + } + + _entriesCount.setText(getResources().getQuantityString(R.plurals.qr_count, _authInfos.size(), _currentEntryCount, _authInfos.size())); @ColorInt int backgroundColor = Color.WHITE; if (getConfiguredTheme() == Theme.LIGHT) { @@ -118,7 +128,7 @@ public class TransferEntriesActivity extends AegisActivity { Bitmap bitmap; try { bitmap = QrCodeHelper.encodeToBitmap(selectedEntry.getUri().toString(), 512, 512, backgroundColor); - } catch (WriterException e) { + } catch (WriterException | GoogleAuthInfoException e) { Dialogs.showErrorDialog(this, R.string.unable_to_generate_qrcode, e); return; } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/ImportExportPreferencesFragment.java b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/ImportExportPreferencesFragment.java index fae5d7d6..dfd0c397 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/ImportExportPreferencesFragment.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/ImportExportPreferencesFragment.java @@ -22,11 +22,17 @@ import com.beemdevelopment.aegis.BuildConfig; import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.helpers.DropdownHelper; import com.beemdevelopment.aegis.importers.DatabaseImporter; +import com.beemdevelopment.aegis.otp.GoogleAuthInfo; +import com.beemdevelopment.aegis.otp.HotpInfo; +import com.beemdevelopment.aegis.otp.OtpInfo; +import com.beemdevelopment.aegis.otp.TotpInfo; import com.beemdevelopment.aegis.ui.ImportEntriesActivity; +import com.beemdevelopment.aegis.ui.TransferEntriesActivity; import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.beemdevelopment.aegis.ui.tasks.ExportTask; import com.beemdevelopment.aegis.ui.tasks.ImportFileTask; import com.beemdevelopment.aegis.vault.VaultBackupManager; +import com.beemdevelopment.aegis.vault.VaultEntry; import com.beemdevelopment.aegis.vault.VaultFileCredentials; import com.beemdevelopment.aegis.vault.VaultRepository; import com.beemdevelopment.aegis.vault.VaultRepositoryException; @@ -37,6 +43,10 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Random; import javax.crypto.Cipher; @@ -78,6 +88,12 @@ public class ImportExportPreferencesFragment extends PreferencesFragment { startExport(); return true; }); + + Preference googleAuthStyleExportPreference = requirePreference("pref_google_auth_style_export"); + googleAuthStyleExportPreference.setOnPreferenceClickListener(preference -> { + startGoogleAuthenticatorStyleExport(); + return true; + }); } @Override @@ -231,6 +247,52 @@ public class ImportExportPreferencesFragment extends PreferencesFragment { Dialogs.showSecureDialog(dialog); } + private void startGoogleAuthenticatorStyleExport() { + ArrayList toExport = new ArrayList<>(); + for (VaultEntry entry : _vaultManager.getVault().getEntries()) { + String type = entry.getInfo().getType().toLowerCase(); + String algo = entry.getInfo().getAlgorithm(false); + int digits = entry.getInfo().getDigits(); + + if ((Objects.equals(type, TotpInfo.ID) || Objects.equals(type, HotpInfo.ID)) + && digits == OtpInfo.DEFAULT_DIGITS + && Objects.equals(algo, OtpInfo.DEFAULT_ALGORITHM)) { + GoogleAuthInfo info = new GoogleAuthInfo(entry.getInfo(), entry.getName(), entry.getIssuer()); + toExport.add(info); + } + } + + int entriesSkipped = _vaultManager.getVault().getEntries().size() - toExport.size(); + if (entriesSkipped > 0) { + Toast a = new Toast(requireContext()); + a.setText(requireContext().getResources().getQuantityString(R.plurals.pref_google_auth_export_incompatible_entries, entriesSkipped, entriesSkipped)); + a.show(); + } + + int qrSize = 10; + int batchId = new Random().nextInt(); + int batchSize = toExport.size() / qrSize + (toExport.size() % qrSize == 0 ? 0 : 1); + List infos = new ArrayList<>(); + ArrayList exports = new ArrayList<>(); + for (int i = 0, batchIndex = 0; i < toExport.size(); i++) { + infos.add(toExport.get(i)); + if (infos.size() == qrSize || toExport.size() == i + 1) { + exports.add(new GoogleAuthInfo.Export(infos, batchId, batchIndex++, batchSize)); + infos = new ArrayList<>(); + } + } + + if (exports.size() == 0) { + Toast t = new Toast(requireContext()); + t.setText(R.string.pref_google_auth_export_no_data); + t.show(); + } else { + Intent intent = new Intent(requireContext(), TransferEntriesActivity.class); + intent.putExtra("authInfos", exports); + startActivity(intent); + } + } + private static int getExportRequestCode(int spinnerPos, boolean encrypt) { if (spinnerPos == 0) { return encrypt ? CODE_EXPORT : CODE_EXPORT_PLAIN; diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index 32f3a0d2..9a7fa388 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -266,10 +266,6 @@ Няма групи за показване. Добавете групи в екрана за редактиране на запис Няма намерени групи Готово - - %d / %d запис - %d / %d записи - Следващ Предишен Прехвърляне на запис diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index e24bf02c..7387f21e 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -268,12 +268,6 @@ Žádné skupiny k zobrazení. Skupiny můžete přidat z obrazovky úprav položky. Nenalezeny žádné skupiny Hotovo - - %d/%d položka - %d/%d položek - %d/%d položek - %d/%d položek - Další Předchozí Přenést položku diff --git a/app/src/main/res/values-da-rDK/strings.xml b/app/src/main/res/values-da-rDK/strings.xml index 84849e0c..bed9b91e 100644 --- a/app/src/main/res/values-da-rDK/strings.xml +++ b/app/src/main/res/values-da-rDK/strings.xml @@ -295,10 +295,6 @@ Vælg et ikon Ukategoriseret Færdig - - %d / %d post - %d / %d poster - Næste Forrige Overfør post diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index c53fb358..530acdcc 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -295,10 +295,6 @@ Wähle ein Symbol aus Nicht kategorisiert Fertig - - 1 Eintrag - %d / %d Einträge - Weiter Zurück Eintrag übertragen diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml index d600f5b9..cbfd7757 100644 --- a/app/src/main/res/values-el-rGR/strings.xml +++ b/app/src/main/res/values-el-rGR/strings.xml @@ -295,10 +295,6 @@ Επιλέξτε ένα εικονίδιο Μη κατηγοριοποιημένο Ολοκληρώθηκε - - %d / %d καταχώρηση - %d / %d καταχωρήσεις - Επόμενο Προηγούμενο Μεταφορά καταχώρησης diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 88c811ed..fff80bd3 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -294,10 +294,6 @@ Seleccione un icono Sin categorizar Hecho - - %d / %d entrada - %d / %d entradas - Siguiente Anterior Transferir entrada diff --git a/app/src/main/res/values-eu-rES/strings.xml b/app/src/main/res/values-eu-rES/strings.xml index 4bac6a45..61d9fb66 100644 --- a/app/src/main/res/values-eu-rES/strings.xml +++ b/app/src/main/res/values-eu-rES/strings.xml @@ -291,10 +291,6 @@ Aukeratu ikono bat Kategoriarik gabe Eginda - - %d / %d sarrera - %d / %d sarrera - Hurrengoa Aurrekoa Transferitu sarrera diff --git a/app/src/main/res/values-fa-rIR/strings.xml b/app/src/main/res/values-fa-rIR/strings.xml index 4148bd11..58997b8e 100644 --- a/app/src/main/res/values-fa-rIR/strings.xml +++ b/app/src/main/res/values-fa-rIR/strings.xml @@ -257,10 +257,6 @@ هیچ گروهی پیدا نشد. شما می‌توانید در صفحه ویرایش هر آیتم، گروه اضافه کنید. گروهی پیدا نشد انجام شد - - %d / %d آیتم - %d / %d آیتم - بعدی قبلی انتقال آیتم‌ها diff --git a/app/src/main/res/values-fi-rFI/strings.xml b/app/src/main/res/values-fi-rFI/strings.xml index c72d796e..02c93056 100644 --- a/app/src/main/res/values-fi-rFI/strings.xml +++ b/app/src/main/res/values-fi-rFI/strings.xml @@ -281,10 +281,6 @@ Valitse kuvake Luokittelematon Valmis - - %d / %d kohde - %d / %d kohdetta - Seuraava Edellinen Siirrä kohde diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index fe073bd7..424701ce 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -295,10 +295,6 @@ Choisissez une icône Non catégorisé Fait - - %d / %d entrée - %d / %d entrées - Suivant Précédent Transférer une entrée diff --git a/app/src/main/res/values-hi-rIN/strings.xml b/app/src/main/res/values-hi-rIN/strings.xml index 104c931d..4f61ad2b 100644 --- a/app/src/main/res/values-hi-rIN/strings.xml +++ b/app/src/main/res/values-hi-rIN/strings.xml @@ -223,10 +223,6 @@ दिखाए जाने के लिये कोई समूह नहीं हैं। एक प्रविष्टि के संपादन स्क्रीन में समूह जोड़ें कोई समूह नहीं मिले हो गया - - %d / %d प्रविष्टि - %d / %d प्रविष्टियाँ - अगला पिछला प्रविष्टि स्थानांतरित करें diff --git a/app/src/main/res/values-in-rID/strings.xml b/app/src/main/res/values-in-rID/strings.xml index 46d4e0f6..f031e28b 100644 --- a/app/src/main/res/values-in-rID/strings.xml +++ b/app/src/main/res/values-in-rID/strings.xml @@ -285,9 +285,6 @@ Pilih sebuah ikon Tidak Dikategorikan Selesai - - %d / %d entri - Berikutnya Sebelumnya Pindahkan entri diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index a2dc2a44..efe40e80 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -295,10 +295,6 @@ Scegli un\'icona Senza categoria Fine - - %d / %d voce - %d / %d voci - Avanti Indietro Trasferisci voce diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 2d5ee7ed..a43f3c6c 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -286,9 +286,6 @@ アイコンを選択 未分類 完了 - - %d / %d エントリー - 次へ 前へ エントリーを転送 diff --git a/app/src/main/res/values-lv-rLV/strings.xml b/app/src/main/res/values-lv-rLV/strings.xml index e6a8546c..1217b6a0 100644 --- a/app/src/main/res/values-lv-rLV/strings.xml +++ b/app/src/main/res/values-lv-rLV/strings.xml @@ -301,11 +301,6 @@ Izvēlēties ikonu Bez kopas Izpildīts - - %d / %d ierakstiem - %d / %d ierakstiem - %d / %d ierakstiem - Nākamais Iepriekšējais Pārvietot ierakstu diff --git a/app/src/main/res/values-nl-rNL/strings.xml b/app/src/main/res/values-nl-rNL/strings.xml index 493b4074..a086bba0 100644 --- a/app/src/main/res/values-nl-rNL/strings.xml +++ b/app/src/main/res/values-nl-rNL/strings.xml @@ -295,10 +295,6 @@ Kies een icoon Ongecategoriseerd Klaar - - %d / %d item - %d / %d items - Volgende Vorige Item overzetten diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index d8f94cb6..12f87b82 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -298,12 +298,6 @@ Wybierz ikonę Bez kategorii Gotowe - - Wpis %d / %d - Wpis %d / %d - Wpis %d / %d - Wpis %d / %d - Następny Poprzedni Przenieś wpis diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 3fbf66e6..3b37b635 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -295,10 +295,6 @@ Escolha um ícone Sem Categoria Terminado - - %d / %d entrada - %d / %d entradas - Próximo Anterior Transferir entrada diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index a67f1230..1e258a27 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -232,10 +232,6 @@ Não há grupos a serem mostrados. Adicione grupos na tela de edição de uma entrada Nenhum grupo encontrado Concluído - - %d / %d entrada - %d / %d entradas - Próximo Anterior Transferir entrada diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml index dfa3be78..6581216f 100644 --- a/app/src/main/res/values-ro-rRO/strings.xml +++ b/app/src/main/res/values-ro-rRO/strings.xml @@ -301,11 +301,6 @@ Alege o pictogramă Necategorizat Realizat - - %d / %d intrare - %d / %d intrări - %d / %d intrări - Următorul Anteriorul Transfer intrare diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 7881c75e..9f07ba86 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -307,12 +307,6 @@ Выбрать значок Без категории Готово - - %d / %d запись - %d / %d записи - %d / %d записей - %d / %d записей - Следующий Предыдущий Передача записи diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index 21f1d7c7..4957ad02 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -293,10 +293,6 @@ Bir ikon seçin Kategorisiz Tamamlandı - - %d / %d girişi - %d / %d girişleri - Sonraki Önceki Girdiyi aktar diff --git a/app/src/main/res/values-uk-rUA/strings.xml b/app/src/main/res/values-uk-rUA/strings.xml index 4252cac2..86b8625e 100644 --- a/app/src/main/res/values-uk-rUA/strings.xml +++ b/app/src/main/res/values-uk-rUA/strings.xml @@ -276,12 +276,6 @@ Немає груп для показу. Додайте групи на екрані редагування запису Групи не знайдено Готово - - %d / %d запис - %d / %d записів - %d / %d записів - %d / %d записів - Наступний Попередній Передати запис diff --git a/app/src/main/res/values-vi-rVN/strings.xml b/app/src/main/res/values-vi-rVN/strings.xml index a82e3852..3371e8fc 100644 --- a/app/src/main/res/values-vi-rVN/strings.xml +++ b/app/src/main/res/values-vi-rVN/strings.xml @@ -289,9 +289,6 @@ Chọn biểu tượng Chưa được phân loại Xong - - %d / %d mục - Tiếp Trước Truyền mục diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 7bd609f1..026c514d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -289,9 +289,6 @@ 选择一个图标 未分类 完成 - - %d / %d 项条目 - 下一个 上一个 迁移条目 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index ad8e8d81..3ec74347 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -250,9 +250,6 @@ 沒有可以顯示的群組,請先在編輯頁面增加一個群組 找不到任何群組 完成 - - %d / %d 條目 - 下一個 上一個 轉移條目 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c4a3931f..ed3b120d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -63,6 +63,13 @@ Export Export the vault Password reminder + Export for Google Authenticator + Generates export QR codes compatible with Google Authenticator + No data to export + + Skipped %d incompatible entry + Skipped %d incompatible entries + Show a %s reminder to enter the password, so that you don\'t forget it. Disabled Screen security @@ -368,14 +375,15 @@ Pick an icon Uncategorized Done - - %d / %d entry - %d / %d entries + + %d / %d QR code + %d / %d QR codes Next Previous Transfer entry Scan this QR code with the authenticator app you would like to transfer this entry to + Scan these QR codes with Aegis or Google Authenticator.\n\nDue to limitations of the Google Authenticator app, only TOTP & HOTP tokens that use SHA1 and produce 6-digit codes are included Very weak Weak diff --git a/app/src/main/res/xml/preferences_import_export.xml b/app/src/main/res/xml/preferences_import_export.xml index 25e8a554..bef016a0 100644 --- a/app/src/main/res/xml/preferences_import_export.xml +++ b/app/src/main/res/xml/preferences_import_export.xml @@ -17,4 +17,9 @@ android:title="@string/pref_export_title" android:summary="@string/pref_export_summary" app:iconSpaceReserved="false"/> + \ No newline at end of file