From 70ee24d82a220b0d3d7b18a51f429bfab7318078 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 15:58:33 +0200 Subject: [PATCH 01/32] Autosync the updated translations (#2099) Co-authored-by: github-actions <> --- src/App/Resources/AppResources.be.resx | 242 ++++++++++++------------- src/App/Resources/AppResources.ko.resx | 6 +- src/App/Resources/AppResources.pl.resx | 20 +- src/App/Resources/AppResources.ro.resx | 2 +- src/App/Resources/AppResources.tr.resx | 40 ++-- store/google/be/copy.resx | 2 +- 6 files changed, 156 insertions(+), 156 deletions(-) diff --git a/src/App/Resources/AppResources.be.resx b/src/App/Resources/AppResources.be.resx index 7447e6f1c..662cf1ac9 100644 --- a/src/App/Resources/AppResources.be.resx +++ b/src/App/Resources/AppResources.be.resx @@ -148,15 +148,15 @@ Cancel an operation. - Капіяваць + Скапіяваць Copy some value to your clipboard. - Капіяваць пароль + Скапіяваць пароль The button text that allows a user to copy the login's password to their clipboard. - Капіяваць імя карыстальніка + Скапіяваць імя карыстальніка The button text that allows a user to copy the login's username to their clipboard. @@ -236,7 +236,7 @@ The button text that allows user to launch the website to their web browser. - Дапамога і зваротная сувязь + Даведка і зваротная сувязь Схаваць @@ -371,7 +371,7 @@ Label for a username. - Поле {0} абавязковае. + Поле {0} з'яўляецца абавязковым. Validation message for when a form field is left blank and is required to be entered. @@ -382,22 +382,22 @@ Праверка адбітка пальца - Праверыць асноўны пароль + Праверка асноўнага пароля - Праверыць PIN-код + Праверка PIN Версія - Выгляд + Прагляд Наведайце наш вэб-сайт - Наведайце наш вэб-сайт, каб атрымаць дапамогу, прачытаць навіны, звязацца з намі і/або даведацца больш пра тое, як карыстацца Bitwarden. + Наведайце наш вэб-сайт, каб атрымаць дапамогу, прачытаць апошнія навіны, звязацца з намі і/або даведацца больш пра тое, як карыстацца Bitwarden. Вэб-сайт @@ -410,7 +410,7 @@ Уліковы запіс - Ваш уліковы запіс створаны! Вы можаце ўвайсці. + Ваш уліковы запіс створаны! Цяпер вы можаце ўвайсці ў яго. Дадаць элемент @@ -419,7 +419,7 @@ Дадаць пашырэнне - Выкарыстоўвайце службу спецыяльных магчымасцяў Bitwarden для аўтазапаўнення вашых уліковых даных у праграмах і інтэрнэце. + Выкарыстоўвайце службу спецыяльных магчымасцей Bitwarden для аўтазапаўнення вашых лагінаў у разнастайных праграмах. Служба аўтазапаўнення @@ -431,28 +431,28 @@ Праграмнае пашырэнне Bitwarden - Самы просты спосаб дадаць новыя ўліковыя даныя ў ваша сховішча — гэта служба аўтаўапаўнення Bitwarden. Дадатковыя звесткі аб выкарыстанні службы аўтазапаўнення Bitwarden у раздзеле "Налады". + Самым простым спосаб дадаць новыя лагіны ў ваша сховішча з'яўляецца выкарыстанне пашырэння Bitwarden. Дадатковыя звесткі пра выкарыстанне гэтага пашырэння можна знайсці ў раздзеле "Налады". - Выкарыстоўвайце Bitwarden у Safari і іншых праграмах для аўтазапаўнення ўліковых даных. + Выкарыстоўвайце Bitwarden у Safari і іншых праграмах для аўтазапаўнення лагінаў. Служба аўтазапаўнення Bitwarden - Выкарыстоўвайце службу спецыяльных магчымасцяў Bitwarden для аўтазапаўнення вашых уліковых даных у праграмах і інтэрнэце. + Выкарыстоўвайце службу спецыяльных магчымасцей Bitwarden для аўтазапаўнення вашых лагінаў. Змяніць адрас электроннай пошты - Вы можаце змяніць сваю электронную пошту на bitwarden.com. Перайсці на сайт зараз? + Вы можаце змяніць сваю электронную пошту ў вэб-сховішчы на bitwarden.com. Перайсці на вэб-сайт зараз? Змяніць асноўны пароль - Вы можаце змяніць свой асноўны пароль на bitwarden.com. Перайсці на сайт зараз? + Вы можаце змяніць свой асноўны пароль у вэб-сховішчы на bitwarden.com. Перайсці на вэб-сайт зараз? Закрыць @@ -496,16 +496,16 @@ Усё гатова для ўваходу! - Цяпер вашыя ўліковыя даныя лёгка даступны з Safari, Chrome і іншых праграм. + Цяпер вы лёгка можаце атрымаць доступ да вашых лагінаў з Safari, Chrome і іншых праграм, якія падтрымліваюцца Bitwarden. У Safari і Chrome, знайдзіце Bitwarden з дапамогай значка абагульнення (падказка: прагартайце ўправа ў ніжнім радку меню абагуліць). - Націсніце на значок Bitwarden у меню, каб запусціць пашырэнне. + Дакраніцеся да значка Bitwarden у меню, каб запусціць пашырэнне. - Каб уключыць Bitwarden у Safari і іншых праграмах, націсніце 'Яшчэ' у ніжнім радку меню. + Дакраніцеся "яшчэ" у ніжнім радку меню, каб уключыць Bitwarden у Safari і іншых праграмах. Абраны @@ -523,7 +523,7 @@ Імпартаванне элементаў - Вы можаце імпартаваць свае элементы ў сваё вэб-сховішча. Перайсці на сайт зараз? + Вы можаце зрабіць масавае імпартаванне элементаў з вэб-сховішча bitwarden.com. Перайсці на вэб-сайт зараз? Хуткае імпартаванне вашых элементаў з іншых менеджараў пароляў. @@ -553,10 +553,10 @@ Адразу - Тайм-аўт сховішча + Час чакання сховішча - Дзеянне пры тайм-аўце + Дзеянне пасля заканчэння часу чакання сховішча Выхад з сістэмы скасуе ўсе магчымасці доступу да сховішча і запатрабуе аўтэнтыфікацыю праз інтэрнэт пасля завяршэння часу чакання. Вы ўпэўнены, што хочаце выкарыстоўваць гэты параметр? @@ -575,7 +575,7 @@ Няправільна пацвярджэнне пароля. - Асноўны пароль — ключ да вашага бяспечнага сховішча. Ён вельмі важны, таму не забывайце яго. Аднавіць асноўны пароль немагчыма. + Асноўны пароль — гэта ключ, які выкарыстоўваецца для доступу да вашага сховішча. Ён вельмі важны, таму не забывайце яго. Аднавіць асноўны пароль немагчыма ў выпадку, калі вы яго забылі. Падказка да асноўнага пароля (неабавязкова) @@ -584,7 +584,7 @@ Падказка да асноўнага пароля можа дапамагчы вам успомніць яго, калі вы яго забылі. - Асноўны пароль павінен быць даўжынёй прынамсі 8 сімвалаў. + Асноўны пароль павінен змяшчаць прынамсі 8 сімвалаў. Мінімум лічбаў @@ -607,16 +607,16 @@ Створаны новы элемент. - У вашым сховішчы няма абранага. + У вашым сховішчы адсутнічаюць абраныя. - У вашым сховішчы няма элементаў. + У вашым сховішчы адсутнічаюць элементы. - У вашым заданні няма элементаў для гэтага сайта/праграмы. Націсніце, каб дадаць. + У вашым сховішчы адсутнічаюць элементы для гэтага вэб-сайта або праграмы. Дакраніцеся, каб дадаць. - У гэтых уліковых даных адсутнічае імя карыстальніка або пароль. + Гэты лагін не мае сканфігураванага імя карыстальніка або пароля. Зразумела! @@ -641,7 +641,7 @@ Падказка да пароля - Мы адправілі вам на электронную пошту падказку для асноўнага пароля. + Мы адправілі вам на электронную пошту падказку да асноўнага пароля. Вы ўпэўнены, што хочаце перазапісаць бягучы пароль? @@ -672,7 +672,7 @@ Выбраць - Прызначыць PIN-код + Прызначыць PIN Увядзіце PIN-код з чатырох лічбаў, каб разблакіраваць праграму. @@ -695,7 +695,7 @@ Сінхранізацыя завершана. - Памылка сінхранізацыі. + Збой сінхранізацыі. Сінхранізаваць сховішча зараз. @@ -708,7 +708,7 @@ Двухэтапны ўваход - Двухэтапны ўваход робіць ваш уліковы запіс больш бяспечным, патрабуючы пацвярджэння ўваходу на іншай прыладзе, напрыклад, ключом бяспекі, праграмай для праверкі бяспекі, SMS, тэлефонным выклікам або электроннай поштай. Двухэтапны ўваход уключаецца на bitwarden.com. Перайсці на сайт зараз? + Двухэтапны ўваход робіць ваш уліковы запіс больш бяспечным, патрабуючы пацвярджэнне ўваходу на іншай прыладзе з выкарыстаннем ключа бяспекі, праграмы аўтэнтыфікацыі, SMS, тэлефоннага званка або электроннай пошты. Двухэтапны ўваход уключаецца на bitwarden.com. Перайсці на сайт, каб зрабіць гэта? Разблакіраваць з {0} @@ -721,10 +721,10 @@ Message shown when interacting with the server - Код праверкі + Праверачны код - Прагляд элемента + Прагледзець элемент Вэб-сховішча Bitwarden @@ -750,17 +750,17 @@ This is used for the autofill service. ex. "Logins for twitter.com" - У вашым сховішчы няма элементаў для {0}. + У вашым сховішчы адсутнічаюць элементы для {0}. This is used for the autofill service. ex. "There are no items in your vault for twitter.com". - Калі пры выбары поля ўводу вы бачыце панэль аўтазапаўнення Bitwarden, вы можаце націснуць на яе, каб запусціць службу аўтазапаўнення. + Калі пры выбары поля ўводу вы бачыце накладанне аўтазапаўнення Bitwarden, вы можаце дакрануцца да яго, каб запусціць службу аўтазапаўнення. - Націсніце на гэта апавяшчэнне для аўтазапаўнення. + Дакраніцеся да гэтага апавяшчэння, каб аўтазапоўніць элемент са свайго сховішча. - Адкрыць налады спецыяльных магчымасцяў + Адкрыць налады спецыяльных магчымасцей 1. На экране наладаў Android у раздзеле "Спецыяльных магчымасці" пад загалоўкам "Сэрвісы" выберыце "Bitwarden". @@ -781,10 +781,10 @@ Уключана - Стан + Статус - Самы просты спосаб дадаць новыя лагіны ў ваша сховішча - служба аўтазапаўнення Bitwarden. Дадатковыя звесткі пра выкарыстанне службы аўтазапаўнення Bitwarden можна знайсці ў раздзеле "Налады". + Самым простым спосаб дадаць новыя лагіны ў ваша сховішча з'яўляецца выкарыстанне службы аўтазапаўнення Bitwarden. Дадатковыя звесткі пра выкарыстанне гэтага пашырэння можна знайсці ў раздзеле "Налады". Аўтазапаўненне @@ -819,11 +819,11 @@ For 2FA - Увядзіце 6 лічбаў кода праверкі з вашай праграмы аўтэнтыфікацыі. + Увядзіце 6 лічбаў праверачнага кода з вашай праграмы аўтэнтыфікацыі. For 2FA - Увядзіце 6 лічбаў кода праверкі, які быў адпраўлены на {0}. + Увядзіце 6 лічбаў праверачнага кода, які быў адпраўлены на {0}. For 2FA @@ -831,7 +831,7 @@ For 2FA whenever there are no available providers on this device. - Для гэтага ўліковага запісу ўключаны двухэтапны уваход, аднак ніводны з наладжаных варыянтаў уваходу не падтрымліваецца на гэтай прыладзе. Выкарыстоўвайце прыладу, якая падтрымліваецца і/або дадайце іншыя варыянты, якія падтрымліваюцца на большасці прылад (напрыклад, праграма для аўтэнтыфікацыі). + Для гэтага ўліковага запісу ўключаны двухэтапны ўваход, між тым ніводны з сканфігураваных пастаўшчыкоў двухэтапнага ўваходу не падтрымліваецца на гэтай прыладзе. Калі ласка, скарыстайцеся прыладай, якая падтрымлівае гэту тэхналогію і/або дадайце іншых пастаўшчыкоў, якія падтрымліваюцца на большасці прылад (напрыклад, праграма для аўтэнтыфікацыі). Код аднаўлення @@ -842,7 +842,7 @@ Remember my two-step login - Адправіць код пацвярджэння зноў + Адправіць праверачны код яшчэ раз For 2FA @@ -860,7 +860,7 @@ For 2FA - Для працягу прыкладзіце ваш YubiKey NEO да задняй панэлі прылады ці устаўце YubiKey ў USB-порт вашай прылады і націсніце на ім кнопку. + Для працягу прыкладзіце ваш YubiKey NEO да задняй панэлі прылады або ўстаўце YubiKey у порт USB вашай прылады і дакраніцеся да яго кнопкі. Ключ бяспекі YubiKey @@ -876,21 +876,21 @@ Немагчыма спампаваць файл. - Прылада ня можа адкрыць гэты тып файла. + Ваша прылада не можа адкрыць файл гэтага тыпу. Спампоўванне... Message shown when downloading a file - Гэтае улажэнне мае памер {0}. Вы сапраўды жадаеце спампаваць яго? + Гэта далучэнне мае памер {0}. Вы ўпэўнены, што хочаце спампаваць яго на сваю прыладу? The placeholder will show the file size of the attachment. Ex "25 MB" Ключ аўтэнтыфікацыі (TOTP) - Код праверкі (TOTP) + Праверачны код (TOTP) Totp code label @@ -912,13 +912,13 @@ Фота - Капіяваць TOTP + Скапіяваць TOTP - Калі падчас уваходу выкарыстоўваецца ключ аўтэнтыфікацыі, то неабходна скапіяваць код праверкі TOTP у буфер абмену пры аўтазапаўненні ўваходу. + Калі падчас уваходу выкарыстоўваецца ключ аўтэнтыфікацыі, то неабходна скапіяваць праверачны код TOTP у буфер абмену пры аўтазапаўненні ўваходу. - Капіяваць TOTP аўтаматычна + Скапіяваць TOTP аўтаматычна Для выкарыстання гэтай функцыі патрабуецца прэміяльны статус. @@ -939,7 +939,7 @@ Файл не выбраны - Няма далучэнняў. + Далучэнні адсутнічаюць. Крыніца файла @@ -951,7 +951,7 @@ Максімальны памер файла 100 МБ. - Вы не можаце выкарыстоўваць гэту функцыю, пакуль не абнавіце свой ключ шыфравання. + Вы не зможаце выкарыстоўваць гэту функцыю, пакуль не абнавіце свой ключ шыфравання. Даведацца больш @@ -969,7 +969,7 @@ URL-адрас сервера асяроддзя захаваны. - {0} гэта няправільны фармат. + {0} з'яўляецца няправільным фарматам. Validation error when something is not formatted correctly, such as a URL or email address. @@ -980,7 +980,7 @@ Асяроддзе ўласнага хостынгу - Увядзіце асноўны URL-адрас на вашым серверы. + Увядзіце асноўны URL-адрас вашага лакальнага размяшчэння ўсталяванага Bitwarden. URL-адрас сервера @@ -989,16 +989,16 @@ URL-адрас сервера вэб-сховішча - Націсніце на гэта апавяшчэнне, каб праглядзець элементы з вашага сховішча. + Дакраніцеся да гэтага апавяшчэння, каб прагледзець элементы са свайго сховішча. Карыстальніцкія палі - Капіяваць нумар + Скапіяваць нумар - Капіяваць код бяспекі + Скапіяваць код бяспекі Нумар @@ -1139,7 +1139,7 @@ Паказваць значкі вэб-сайтаў - Паказваць распазнавальны відарыс побач з кожным з кожным лагінам. + Паказваць распазнавальны відарыс побач з кожным лагінам. URL-адрас сервера значкоў @@ -1157,22 +1157,22 @@ Калекцыі - Няма элементаў у гэтай калекцыі. + У гэтай калекцыі адсутнічаюць элементы. - Няма элементаў у гэтай папцы. + У гэтай папцы адсутнічаюць элементы. - У сметніцы нічога няма. + У сметніцы адсутнічаюць элементы. - Служба спецыяльных магчымасцяў аўтазапаўнення + Служба спецыяльных магчымасцей аўтазапаўнення - Служба аўтазапаўнення Bitwarden карыстаецца Android Autofill Framework для запаўнення ўліковых даных, нумароў карт і асабістай інфармацыі ў іншых праграмах на вашай прыладзе. + Служба аўтазапаўнення Bitwarden выкарыстоўвае Android Autofill Framework для запаўнення ўліковых даных у іншых праграмах на вашай прыладзе. - Карыстайцеся службай аўтазапаўнення Bitwarden для запаўнення ўліковых даных, нумароў карт і асабістай інфармацыі ў іншых праграмах. + Выкарыстоўвайце службу аўтазапаўнення Bitwarden для запаўнення інфармацыі пра лагіны ў іншых праграмах. Адкрыць налады аўтазапаўнення @@ -1194,7 +1194,7 @@ Windows Hello - Не атрымалася аўтаматычна адчыніць меню налад аўтазапаўнення Android. Вы можаце перайсці ў меню налад аўтазапаўнення з налад Android -> Сістэма -> Мова -> Мова і спосабы ўводу -> Дадатковыя налады -> Служба аўтазапаўнення. + Немагчыма аўтаматычна адкрыць меню наладаў аўтазапаўнення Android. Вы можаце перайсці ў меню наладаў аўтазапаўнення ўручную з Налады Android > Сістэма > Мова і ўвод > Дадаткова > Служба аўтазапаўнення. Карыстальніцкая назва поля @@ -1215,7 +1215,7 @@ Новае карыстальніцкае поле - Які тып карыстальніцкага поля вы жадеце дадаць? + Які тып карыстальніцкага поля вы хочаце дадаць? Выдаліць @@ -1255,7 +1255,7 @@ URI match detection for auto-fill. - Да, і захаваць + Так, і захаваць Аўтазапоўніць і захаваць @@ -1268,13 +1268,13 @@ Трымайце ваш YubiKey каля верхняй часткі прылады. - Паспрабуйце зноў + Паспрабуйце яшчэ раз - Для працягу трымайце YubiKey NEO ля задняй панэлі вашай прылады. + Для працягу прыкладзіце ваш YubiKey NEO да задняй панэлі прылады. - Служба спецыяльных магчымасцей может быць карыснай калі праграмы не падтрымліваюць стандартную службу аўтазапаўнення. + Служба спецыяльных магчымасцей можа быць карыснай, калі праграмы не падтрымліваюць стандартную службу аўтазапаўнення. Пароль абноўлены @@ -1288,19 +1288,19 @@ Аўтазапаўненне актывавана! - Перад выкарыстаннем аўтазапаўнення трэба ўвайсці ў асноўную праграму Bitwarden. + Неабходна ўвайсці ў асноўную праграму Bitwarden, каб выкарыстоўваць аўтазапаўненне. - Цяпер вашы ўліковыя даныя лёгка даступныя з клавіятуры пры ўваходзе ў праграмы і на вэб-сайты. + Цяпер вы лёгка можаце атрымаць доступ да сваіх лагінаў з клавіятуры пры ўваходзе ў праграмы і на вэб-сайты. - Рэкамендуецца адключыць другія праграмы аўтазапаўнення ў наладах, калі яны не выкарыстоўваюцца. + Рэкамендуецца адключыць іншыя праграмы аўтазапаўнення ў наладах, калі вы не плануеце выкарыстоўваць іх. Атрымайце доступ да свайго сховішча непасрэдна з клавіятуры для хуткага аўтазапаўнення. - Для ўключэння аўтазапаўнення паролей на прыладзе трэба выканаць наступныя дзеянні: + Прытрымлівайцеся гэтых інструкцый для таго, каб уключыць аўтазапаўненне пароляў на вашай прыладзе: 1. Перайдзіце ў "Налады" iOS @@ -1321,7 +1321,7 @@ Аўтазапаўненне пароляў - Самы просты спосаб дадаць новыя ўліковыя даныя ў ваша сховішча — гэта праграма Bitwarden Password AutoFill. Дадатковыя звесткі аб выкарыстанні праграмы Bitwarden Password AutoFill у раздзеле "Налады". + Самым простым спосаб дадаць новыя лагіны ў ваша сховішча з'яўляецца выкарыстанне пашырэння Bitwarden Password AutoFill. Дадатковыя звесткі пра выкарыстанне гэтага пашырэння можна знайсці ў раздзеле "Налады". Памылковы адрас электроннай пошты. @@ -1336,7 +1336,7 @@ Лагіны - Бяспечныя нататкі + Абароненыя нататкі Усе элементы @@ -1353,7 +1353,7 @@ Праверце, ці не скампраметаваны пароль. - Гэты пароль быў скампраметаваны {0} раз(-ы/-оў). Вы павінны змяніць яго. + Гэты пароль быў скампраметаваны наступную колькасць разоў: {0}. Вы павінны змяніць яго. Гэты пароль не быў знойдзены ў вядомых базах уцечак. Можна працягваць яго выкарыстоўваць. @@ -1374,7 +1374,7 @@ Няма пароляў для паказу. - Няма элементаў для паказу. + У спісе адсутнічаюць элементы. Пошук у калекцыі @@ -1408,7 +1408,7 @@ Каму належыць гэты элемент? - Няма калекцый для паказу. + У спісе адсутнічаюць калекцыі. {0} перамешчана ў {1}. @@ -1453,7 +1453,7 @@ Short for "Password Generator" - Няма папак для паказу. + У спісе адсутнічаюць папкі. Фраза адбітка пальца @@ -1485,17 +1485,17 @@ 30 хвілін - Задайце PIN-код для разблакіроўкі Bitwarden. Налады PIN-кода будуць скінуты, калі вы калі-небудзь цалкам выйдзеце з праграмы. + Прызначце PIN-код для разблакіроўкі Bitwarden. Налады PIN-кода будуць скінуты, калі вы калі-небудзь цалкам выйдзеце з праграмы. Вы ўвайшлі як {0} у {1}. ex: Logged in as user@example.com on bitwarden.com. - Ваша сховішча заблакіравана. Каб працягнуць, увядзіце асноўны пароль. + Ваша сховішча заблакіравана. Увядзіце асноўны пароль для працягу. - Ваша сховішча заблакіравана. Каб працягнуць, увядзіце PIN-код. + Ваша сховішча заблакіравана. Увядзіце PIN-код для працягу. Ваша сховішча заблакіравана. Пацвердзіце сваю асобу, каб працягнуць. @@ -1555,7 +1555,7 @@ Выбіраць цёмную тэму для яе выкарыстання ў выпадку, калі яна з'яўляецца прадвызначанай (сістэмнай) для вашай прылады. - Капіяваць нататку + Скапіяваць нататку Выхад @@ -1584,7 +1584,7 @@ Пытацца пры дадаванні лагіна - Запытаць дадаванне элемента, калі ён адсутнічае ў вашым сховішчы. + Пытацца пра дадаванне элемента, калі ён адсутнічае ў вашым сховішчы. Пры перазапуску праграмы @@ -1612,7 +1612,7 @@ Пераключыць бачнасць - Скончыўся тэрмін дзеяння вашага сеансу. + Тэрмін дзеяння вашага сеансу завяршыўся. Біяметрычныя праверка @@ -1648,7 +1648,7 @@ Фармат файла - Увядзіце ваш асноўны пароль для экспартавання даных са сховішча. + Увядзіце ваш асноўны пароль для экспартавання даных сховішча. Адправіць праверачны код на ваш адрас электроннай пошты @@ -1657,13 +1657,13 @@ Код адпраўлены! - Пацвердзіце сваю асобу, каб працягнуць. + Пацвердзіце сваю асобу для працягу. - Экспартуемы файл утрымлівае даныя вашага сховішча ў незашыфраваным фармаце. Яго не варта захоўваць ці адпраўляць па небяспечным каналам (напрыклад, па электроннай пошце). Выдаліце яго адразу пасля выкарыстання. + Пры экспартаванні файл утрымлівае даныя вашага сховішча ў незашыфраваным фармаце. Яго не варта захоўваць або адпраўляць па неабароненых каналах (напрыклад, па электроннай пошце). Выдаліце яго адразу пасля выкарыстання. - Пры экспарце даныя шыфруюцца з дапамогай ключа шыфравання ўліковага запісу. Калі вы калі-небудзь павернеце ключ шыфравання ўліковага запісу, вам належыць экспартаваць даныя паўторна, бо вы не зможаце расшыфраваць гэты файл экспарту. + Пры экспартаванні даныя шыфруюцца з дапамогай ключа шыфравання ўліковага запісу. Калі вы калі-небудзь зменіце ключ шыфравання ўліковага запісу, вам неабходна будзе экспартаваць даныя паўторна, паколькі вы не зможаце расшыфраваць гэты файл экспартавання. Ключы шыфравання з'яўляюцца ўнікальнымі для кожнага ўліковага запісу Bitwarden, таму нельга імпартаваць зашыфраванае сховішча ў іншы ўліковы запіс. @@ -1673,10 +1673,10 @@ Title for the alert to confirm vault exports. - Увага + Папярэджанне - Узнікла праблема падчас экспартавання сховішча. Калі праблема застанецца, экспартуйце яго з выб-сховішча. + Узнікла праблема падчас экспартавання вашага сховішча. Калі праблема захаваецца, экспартуйце свае даныя з вэб-сховішча. Сховішча паспяхова экспартавана @@ -1693,13 +1693,13 @@ Button text for an open operation (verb). - Узнікла праблема падчас захавання гэтага далучэння. Калі праблема застанецца, вы можаце захаваць яго з вэб-сховішча. + Узнікла праблема падчас захавання гэтага далучэння. Калі праблема застанецца, вы можаце захаваць іх з вэб-сховішча. Далучэнне паспяхова захавана - Уключыце "Службу спецыяльных магчымасцяў аўтазапаўнення" ў наладах Bitwarden для выкарыстання панэлі аўтазапаўнення. + Уключыце "Службу спецыяльных магчымасцей аўтазапаўнення" ў наладах Bitwarden для выкарыстання панэлі аўтазапаўнення. Палі для пароляў не знойдзены @@ -1833,13 +1833,13 @@ Спецыяльныя магчымасці - Пры дапамозе службы спецыяльных магчымасцей Bitwarden вы можаце аўтаматычна запаўняць вашыя ўліковыя даныя ў праграмах і ў інтэрнэце. Калі гэты параметр адключаны, пры выбары палёў для ўваходу будзе паказвацца ўсплывальнае акно. + Выкарыстоўвайце службу спецыяльных магчымасцей Bitwarden для аўтазапаўнення вашых лагінаў у разнастайных праграмах. Калі гэты параметр уключаны, пры выбары палёў для ўваходу будзе паказана ўсплывальнае акно. - З дапамогай службы спецыяльных магчымасцяў Bitwarden вы можаце аўтаматычна запаўняць вашы ўліковыя даныя ў інтэрнэце (неабходна ўключыць функцыю "Па-над усімі праграмамі") + Выкарыстоўвайце службу спецыяльных магчымасцей Bitwarden для аўтазапаўнення вашых лагінаў у разнастайных праграмах (неабходна ўключыць функцыю "Па-над усімі праграмамі"). - З дапамогай службы спецыяльных магчымасцяў Bitwarden вы можаце выкарыстоўваць панэль хуткага аўтазапаўнення, а таксама для паказу ўсплывальнага акна выкарыстоўваючы параметр "Па-над усімі праграмамі" (калі ён уключаны). + Выкарыстоўвайце службу спецыяльных магчымасцей Bitwarden, каб скарыстацца панэллю хуткага аўтазапаўнення, а таксама для паказу ўсплывальнага акна з выкарыстаннем параметра "Па-над усімі праграмамі" (калі ён уключаны). Патрабуецца для выкарыстання панэлі хуткага аўтазапаўнення або для дапаўнення службы аўтазапаўнення пры выкарыстанні параметра "Па-над усімі праграмамі" (калі ён уключаны). @@ -1848,7 +1848,7 @@ Выкарыстоўваць "Па-над усімі праграмамі" - Пры ўключэнні, дазваляе службе спецыяльных магчымасцей Bitwarden паказваць усплывальную панэль пры выбары палёў для ўваходу. + Калі ўключана, дазваляе службе спецыяльных магчымасцей Bitwarden паказваць усплывальную панэль пры выбары палёў уваходу. Калі ўключана, служба спецыяльных магчымасцей Bitwarden пакажа ўсплывальнае апавяшчэнне пры выбары палёў для ўваходу, каб дапамагчы аўтаматычна запоўніць вашы ўліковыя даныя. @@ -1863,7 +1863,7 @@ Палітыка арганізацыі ўплывае на вашы параметры ўласнасці. - Адпраўленне + Send 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -1871,7 +1871,7 @@ 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Адпраўленні + Send'ы 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -1888,7 +1888,7 @@ Тэкст, які вы хочаце адправіць. - Пры доступе да адпраўлення хаваць тэкст па змаўчанні. + Пры доступе да Send прадвызначана хаваць тэкст 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -1901,13 +1901,13 @@ Тып файла выбраны. - Тып файла не выбраны. Націсніце, каб выбраць. + Тып файла не выбраны. Дакраніцеся, каб выбраць. Тып тэксту выбраны. - Тып тэксту не выбраны. Націсніце, каб выбраць. + Тып тэксту не выбраны. Дакраніцеся, каб выбраць. Дата выдалення @@ -1916,7 +1916,7 @@ Час выдалення - Гэтае адпраўленне аўтаматычна выдаліцца ў вызначаную дату і час. + Send будзе незваротна выдалены ў азначаныя дату і час. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -1976,7 +1976,7 @@ 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - У вашым Send'e няма ўліковых запісаў. + У вашым Send'e адсутнічаюць уліковыя запісы. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -1984,13 +1984,13 @@ 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Капіяваць спасылку + Скапіяваць спасылку - Падзяліцца спасылкай + Абагуліць спасылку - Спасылка на адпраўленне + Спасылка на Send 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2010,11 +2010,11 @@ 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Адпраўленне выдалена. + Send быў выдалены. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Адпраўленне абноўлена. + Send абноўлены. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2040,7 +2040,7 @@ Карыстальніцкі - Падзяліцца адпраўленнем пасля захавання. + Падзяліцца гэтым Send'ам пасля захавання 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2063,7 +2063,7 @@ 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Для адпраўлення файлаў патрэбна пацвердзіць свой адрас электроннай пошты. + Для адпраўкі файлаў з дапамогай Send, вам неабходна праверыць вашу электронную пошту. Зрабіць гэта можна ў вэб-сховішчы. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2073,7 +2073,7 @@ Пацвярджэнне асноўнага пароля - Гэтае дзеянне ахоўваецца, для працягу зноў увядзіце пароль для праверкі асобы. + Гэта дзеянне абаронена. Паўторна ўвядзіце асноўны пароль, каб праверыць сваю асобу і працягнуць далей. Патрабуецца ўвод CAPTCHA @@ -2088,7 +2088,7 @@ Абнавіць асноўны пароль - Ваш галоўны пароль быў нядаўна зменены адміністратарам вашай арганізацыі. Для атрымання доступу да сховішча, вы павінны абнавіць галоўны пароль. Працягваючы, вы выйдзіце з бягучага сеанса і вам неабходна будзе ўвайсці паўторна. Сеансы на іншых прыладах могуць заставацца актыўнымі на працягу адной гадзіны. + Ваш асноўны пароль быў нядаўна зменены адміністратарам вашай арганізацыі. Для атрымання доступу да сховішча, вы павінны абнавіць яго. Працягваючы, вы выйдзіце з бягучага сеанса і вам неабходна будзе ўвайсці паўторна. Сеансы на іншых прыладах могуць заставацца актыўнымі на працягу адной гадзіны. Абнаўленне пароля @@ -2133,7 +2133,7 @@ Гэта арганізацыя мае карпаратыўную палітыку, якая будзе аўтаматычна зарэгіструе ваша скіданне пароля. Рэгістрацыя дазволіць адміністратарам арганізацыі змяняць ваш асноўны пароль. - Палітыка вашай арганізацыі ўплывае на час чакання сховішча. Максімальны дазволены час чакання сховішча {0} гадз. і {1} хв. + Палітыка вашай арганізацыі ўплывае на час чакання сховішча. Максімальны дазволены час чакання сховішча складае {0} гадз. і {1} хв. Час чакання вашага сховішча перавышае дазволеныя абмежаванні, якія прызначыла ваша арганізацыя. @@ -2211,7 +2211,7 @@ Адбылася памылка пры адпраўцы праверачнага кода на ваш адрас электроннай пошты. Калі ласка, паспрабуйце яшчэ раз - Увядзіце код праверкі, які быў адпраўлены на вашу электронную пошту + Увядзіце праверачны код, які быў адпраўлены на вашу электронную пошту Адпраўляць справаздачы пра збоі @@ -2220,10 +2220,10 @@ Дапамажыце нам палепшыць стабільнасць праграмы, адпраўляючы справаздачы пра памылкі. - Параметры разгорнуты. Націсніце, каб згарнуць. + Параметры разгорнуты. Дакраніцеся, каб згарнуць. - Параметры згорнуты. Націсніце, каб разгарнуць. + Параметры згорнуты. Дакраніцеся, каб разгарнуць. Вялікія літары (A-Z) @@ -2238,7 +2238,7 @@ Спецыяльныя сімвалы (!@#$%^&*) - Націсніце, каб вярнуцца + Дакраніцеся, каб вярнуцца Пароль бачны. Дакраніцеся, каб схаваць. @@ -2377,7 +2377,7 @@ Адбылася невядомая памылка {0}. - Выкарыстоўваць магчымасці пададрасацыі вашага пастаўшчыка паслуг электроннай пошты + Выкарыстоўваце магчымасці пададрасацыі вашага пастаўшчыка паслуг электроннай пошты Выкарыстоўвайце сваю сканфігураваную скрыню для ўсёй пошты дамена. diff --git a/src/App/Resources/AppResources.ko.resx b/src/App/Resources/AppResources.ko.resx index e65e2b393..2683ea22f 100644 --- a/src/App/Resources/AppResources.ko.resx +++ b/src/App/Resources/AppResources.ko.resx @@ -300,7 +300,7 @@ The title for the vault page. - Authenticator + 인증기 Authenticator TOTP feature @@ -775,10 +775,10 @@ 켜짐 - Off + 끄기 - On + 켜기 상태 diff --git a/src/App/Resources/AppResources.pl.resx b/src/App/Resources/AppResources.pl.resx index 1c10c639e..ba3b19fd8 100644 --- a/src/App/Resources/AppResources.pl.resx +++ b/src/App/Resources/AppResources.pl.resx @@ -300,7 +300,7 @@ The title for the vault page. - Uwierzytelniacz + Authenticator Authenticator TOTP feature @@ -1140,7 +1140,7 @@ Skanowanie nastąpi automatycznie. Pokaż ikony witryn - Pokaż rozpoznawalny obraz obok każdych danych logowania. + Pokaż rozpoznawalny obraz obok danych logowania. Adres URL serwera ikon @@ -1898,16 +1898,16 @@ Skanowanie nastąpi automatycznie. Plik, który chcesz wysłać. - Wybrano typ pliku. + Wybrano rodzaj pliku. - Nie wybrano typu pliku, dotknij, aby go wybrać. + Nie wybrano rodzaju pliku. Kliknij, aby go wybrać. - Wybrano typ tekstowy. + Wybrano rodzaj tekstu. - Nie wybrano typu tekstowego, dotknij, aby go wybrać. + Nie wybrano rodzaju tekstu. Kliknij, aby go wybrać. Data usunięcia @@ -2241,10 +2241,10 @@ Skanowanie nastąpi automatycznie. Dotknij, aby wrócić - Hasło jest widoczne, dotknij, aby je ukryć. + Hasło jest widoczne. Kliknij, aby je ukryć. - Hasło jest niewidoczne, dotknij, aby je pokazać. + Hasło nie jest widoczne. Kliknij, aby je pokazać. Filtruj elementy według sejfu @@ -2283,7 +2283,7 @@ Skanowanie nastąpi automatycznie. Klucz uwierzytelniający - Wprowadź klucz ręcznie + Wpisz klucz ręcznie Dodaj TOTP @@ -2368,7 +2368,7 @@ wybierz Dodaj TOTP, aby bezpiecznie przechowywać klucz Wygeneruj nazwę użytkownika - Typ e-maila + Rodzaj adresu Strona internetowa (wymagana) diff --git a/src/App/Resources/AppResources.ro.resx b/src/App/Resources/AppResources.ro.resx index 75fdeef5e..c196db419 100644 --- a/src/App/Resources/AppResources.ro.resx +++ b/src/App/Resources/AppResources.ro.resx @@ -2256,7 +2256,7 @@ Scanarea se va face automat. Seifuri - Seif: (0} + Seif: {0} Toate diff --git a/src/App/Resources/AppResources.tr.resx b/src/App/Resources/AppResources.tr.resx index edd1583e8..13320c838 100644 --- a/src/App/Resources/AppResources.tr.resx +++ b/src/App/Resources/AppResources.tr.resx @@ -553,7 +553,7 @@ Hemen - Kasa Zaman Aşımı + Kasa zaman aşımı Kasa zaman aşımı eylemi @@ -663,7 +663,7 @@ Ana parolayı tekrar yazın - Kasada Ara + Kasada ara Güvenlik @@ -727,7 +727,7 @@ Kaydı görüntüle - Bitwarden Web Kasası + Bitwarden web kasası Kimlik doğrulama uygulamanızı kayıp mı ettiniz? @@ -916,7 +916,7 @@ Kod otomatik olarak taranacaktır. TOTP'yi kopyala - Hesabınıza bağlı bir kimlik doğrulama anahtarı varsa giriş bilgilerini otomatik olarak doldurduğunuzda TOTP doğrulama kodu da otomatik olarak panonuza kopyalanır. + Hesabınıza bağlı bir kimlik doğrulama anahtarı varsa giriş bilgilerini otomatik doldurduğunuzda TOTP doğrulama kodu panonuza kopyalanır. TOTP'yi otomatik kopyala @@ -1307,7 +1307,7 @@ Kod otomatik olarak taranacaktır. 1. iOS'te "Ayarlar" uygulamasını açın - 2. "Parolalar ve Hesaplar"a dokunun + 2. "Parolalar"a dokunun 3. "Parolaları Oto. Doldur"a dokunun @@ -1457,7 +1457,7 @@ Kod otomatik olarak taranacaktır. Listelenecek klasör yok. - Parmak izi kelimeleri + Parmak izi ifadesi A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing. @@ -1468,7 +1468,7 @@ Kod otomatik olarak taranacaktır. Bitwarden, kuruluş hesabı kullanarak kasanızdaki kayıtları başkalarıyla paylaşmanıza olanak verir. Daha fazla bilgi için bitwarden.com sitesini ziyaret etmek ister misiniz? - Kasayı Dışa Aktar + Kasayı dışa aktar Şimdi kilitle @@ -1553,10 +1553,10 @@ Kod otomatik olarak taranacaktır. Varsayılan koyu tema - Varsayılan (sistem) temayı kullanırken cihazınızın koyu modu açıldığında koyu temaya geçmek için bunu seçin + Varsayılan (sistem) temayı kullanırken cihazınızın koyu modu açıldığında koyu temaya geçmek için bunu seçin. - Notları kopyala + Notu kopyala Çıkış @@ -1576,10 +1576,10 @@ Kod otomatik olarak taranacaktır. 'Nord' is the name of a specific color scheme. It should not be translated. - Auto-fill blocked URIs + Engellenmiş URI'leri otomatik doldur - Auto-fill will not be offered for blocked URIs. Separate multiple URIs with a comma. For example: "https://twitter.com, androidapp://com.twitter.android". + Engellenen URI'lerde otomatik doldurma önerilmeyecektir. Birden fazla URI'yi virgülle ayırabilirsiniz. Örnek: "https://twitter.com, androidapp://com.twitter.android". Hesap eklemeyi öner @@ -1898,16 +1898,16 @@ Kod otomatik olarak taranacaktır. Göndermek istediğiniz dosya. - Dosya türü seçilmiş. + Dosya türü seçildi. - Dosya türü seçilmemiş, seçmek için dokunun. + Dosya türü seçilmedi. Seçmek için dokunun. - Yazı türü seçildi. + Metin türü seçildi. - Yazı türü seçilmemiş, seçmek için dokunun. + Metin türü seçilmedi. Seçmek için dokunun. Silinme tarihi @@ -2172,7 +2172,7 @@ Kod otomatik olarak taranacaktır. Silinen hesaplar geri getirilemez - Hesabınız ve içindeki tüm veriler kalıcı olarak silinecektir. Devam etmek istediğinizden emin misiniz? + Hesabınız ve kasanızdaki tüm veriler kalıcı olarak silinecektir. Devam etmek istediğinizden emin misiniz? Hesabınız siliniyor @@ -2307,10 +2307,10 @@ Kod otomatik olarak taranacaktır. İsteğinizi işleyemedik. Lütfen yeniden deneyin veya bizimle iletişime geçin. - Ekran yakalamaya izin ver + Ekran kaydına izin ver - Ekran Yakalama özelliğini etkinleştirmek istediğinizden emin misiniz? + Ekran kaydını etkinleştirmek istediğinizden emin misiniz? Parola türü @@ -2373,10 +2373,10 @@ Kod otomatik olarak taranacaktır. Web sitesi (gerekli) - Bilinmeyen {0} hata oluştu. + Bilinmeyen {0} hatası oluştu. - Use your email provider's subaddress capabilities + E-posta sağlayıcınızın alt adres özelliklerini kullanın Alan adınızın tüm iletileri yakalamaya ayarlanmış adresini kullanın. diff --git a/store/google/be/copy.resx b/store/google/be/copy.resx index b8a9f32ac..f9d78099c 100644 --- a/store/google/be/copy.resx +++ b/store/google/be/copy.resx @@ -175,6 +175,6 @@ Bitwarden перакладзены на 40 моў свету (прысутніч - тэлефон - планшэт - камп'ютар -- Web-браузер +- браўзер From 2f4cd36595023095d77e857e9bbc7ce3761ccff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bispo?= Date: Mon, 26 Sep 2022 17:51:03 +0100 Subject: [PATCH 02/32] [SG-671] OTP Menu Screen causes Crash on Android (#2097) * [SG-671] removed unnecessary calc of otpauth period. protected cal of otpauth from crashing the app if url has a wrong format. * [SG-671] changed logger * [SG-671] Refactored GetQueryParams code to used HttpUtility.ParseQueryString. * [SG-671] refactor and null protection. * [SG-671] code format * [SG-671] fixed bug where totp circle countdown was fixed to 30. * [SG-167] added fallback for uri check. Changed all default totp timers to constant. * [SG-671] missed unsaved file * [SG-671] simplified code --- .../Pages/Vault/CipherDetailsPageViewModel.cs | 8 +++--- .../GroupingsPageTOTPListItem.cs | 2 -- src/App/Utilities/TotpHelper.cs | 11 ++++---- src/Core/Constants.cs | 1 + src/Core/Services/TotpService.cs | 4 +-- src/Core/Utilities/CoreHelpers.cs | 28 ++++++++----------- 6 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/App/Pages/Vault/CipherDetailsPageViewModel.cs b/src/App/Pages/Vault/CipherDetailsPageViewModel.cs index 0c0411427..f6e7e3452 100644 --- a/src/App/Pages/Vault/CipherDetailsPageViewModel.cs +++ b/src/App/Pages/Vault/CipherDetailsPageViewModel.cs @@ -40,8 +40,8 @@ namespace Bit.App.Pages private string _totpCode; private string _totpCodeFormatted; private string _totpSec; + private double _totpInterval = Constants.TotpDefaultTimer; private bool _totpLow; - private DateTime? _totpInterval = null; private string _previousCipherId; private byte[] _attachmentData; private string _attachmentFilename; @@ -241,7 +241,7 @@ namespace Bit.App.Pages Page.Resources["textTotp"] = ThemeManager.Resources()[value ? "text-danger" : "text-default"]; } } - public double TotpProgress => string.IsNullOrEmpty(TotpSec) ? 0 : double.Parse(TotpSec) * 100 / 30; + public double TotpProgress => string.IsNullOrEmpty(TotpSec) ? 0 : double.Parse(TotpSec) * 100 / _totpInterval; public bool IsDeleted => Cipher.IsDeleted; public bool CanEdit => !Cipher.IsDeleted; @@ -265,6 +265,7 @@ namespace Bit.App.Pages { _totpTickHelper = new TotpHelper(Cipher); _totpTickCancellationToken?.Cancel(); + _totpInterval = _totpTickHelper.Interval; _totpTickCancellationToken = new CancellationTokenSource(); _totpTickTask = new TimerTask(_logger, StartCiphersTotpTick, _totpTickCancellationToken).RunPeriodic(); } @@ -284,6 +285,7 @@ namespace Bit.App.Pages await _totpTickHelper.GenerateNewTotpValues(); TotpSec = _totpTickHelper.TotpSec; TotpCodeFormatted = _totpTickHelper.TotpCodeFormatted; + _totpInterval = _totpTickHelper.Interval; } catch (Exception ex) { @@ -429,7 +431,6 @@ namespace Bit.App.Pages { if (Cipher == null || Cipher.Type != Core.Enums.CipherType.Login || Cipher.Login.Totp == null) { - _totpInterval = null; return; } _totpCode = await _totpService.GetCodeAsync(Cipher.Login.Totp); @@ -449,7 +450,6 @@ namespace Bit.App.Pages else { TotpCodeFormatted = null; - _totpInterval = null; } } diff --git a/src/App/Pages/Vault/GroupingsPage/GroupingsPageTOTPListItem.cs b/src/App/Pages/Vault/GroupingsPage/GroupingsPageTOTPListItem.cs index 7a49ef857..45b920ace 100644 --- a/src/App/Pages/Vault/GroupingsPage/GroupingsPageTOTPListItem.cs +++ b/src/App/Pages/Vault/GroupingsPage/GroupingsPageTOTPListItem.cs @@ -22,7 +22,6 @@ namespace Bit.App.Pages private bool _websiteIconsEnabled; private string _iconImageSource = string.Empty; - public int interval { get; set; } private double _progress; private string _totpSec; private string _totpCodeFormatted; @@ -37,7 +36,6 @@ namespace Bit.App.Pages Cipher = cipherView; WebsiteIconsEnabled = websiteIconsEnabled; - interval = _totpService.GetTimeInterval(Cipher.Login.Totp); CopyCommand = new AsyncCommand(CopyToClipboardAsync, onException: ex => _logger.Value.Exception(ex), allowsMultipleExecutions: false); diff --git a/src/App/Utilities/TotpHelper.cs b/src/App/Utilities/TotpHelper.cs index 64fc2c7a4..4d4b2e8b9 100644 --- a/src/App/Utilities/TotpHelper.cs +++ b/src/App/Utilities/TotpHelper.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Bit.Core; using Bit.Core.Abstractions; using Bit.Core.Models.View; using Bit.Core.Utilities; @@ -10,26 +11,26 @@ namespace Bit.App.Utilities { private ITotpService _totpService; private CipherView _cipher; - private int _interval; public TotpHelper(CipherView cipher) { _totpService = ServiceContainer.Resolve("totpService"); _cipher = cipher; - _interval = _totpService.GetTimeInterval(cipher?.Login?.Totp); + Interval = _totpService.GetTimeInterval(cipher?.Login?.Totp); } public string TotpSec { get; private set; } public string TotpCodeFormatted { get; private set; } public double Progress { get; private set; } + public double Interval { get; private set; } = Constants.TotpDefaultTimer; public async Task GenerateNewTotpValues() { var epoc = CoreHelpers.EpocUtcNow() / 1000; - var mod = epoc % _interval; - var totpSec = _interval - mod; + var mod = epoc % Interval; + var totpSec = Interval - mod; TotpSec = totpSec.ToString(); - Progress = totpSec * 100 / 30; + Progress = totpSec * 100 / Interval; if (mod == 0 || string.IsNullOrEmpty(TotpCodeFormatted)) { TotpCodeFormatted = await TotpUpdateCodeAsync(); diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index 99ef08614..d2cb9800f 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -33,6 +33,7 @@ public const int SelectFileRequestCode = 42; public const int SelectFilePermissionRequestCode = 43; public const int SaveFileRequestCode = 44; + public const int TotpDefaultTimer = 30; public static readonly string[] AndroidAllClearCipherCacheKeys = { diff --git a/src/Core/Services/TotpService.cs b/src/Core/Services/TotpService.cs index 358dfeb51..fe0b83649 100644 --- a/src/Core/Services/TotpService.cs +++ b/src/Core/Services/TotpService.cs @@ -24,7 +24,7 @@ namespace Bit.Core.Services { return null; } - var period = 30; + var period = Constants.TotpDefaultTimer; var alg = CryptoHashAlgorithm.Sha1; var digits = 6; var keyB32 = key; @@ -117,7 +117,7 @@ namespace Bit.Core.Services public int GetTimeInterval(string key) { - var period = 30; + var period = Constants.TotpDefaultTimer; if (key != null && key.ToLowerInvariant().StartsWith("otpauth://")) { var qsParams = CoreHelpers.GetQueryParams(key); diff --git a/src/Core/Utilities/CoreHelpers.cs b/src/Core/Utilities/CoreHelpers.cs index bb3d5586b..027b7a757 100644 --- a/src/Core/Utilities/CoreHelpers.cs +++ b/src/Core/Utilities/CoreHelpers.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +using System.Web; using Bit.Core.Models.Domain; +using Bit.Core.Services; using Newtonsoft.Json; namespace Bit.Core.Utilities @@ -182,26 +184,20 @@ namespace Bit.Core.Utilities public static Dictionary GetQueryParams(string urlString) { - var dict = new Dictionary(); - if (!Uri.TryCreate(urlString, UriKind.Absolute, out var uri) || string.IsNullOrWhiteSpace(uri.Query)) + try { - return dict; + if (!Uri.TryCreate(urlString, UriKind.Absolute, out var uri) || string.IsNullOrWhiteSpace(uri.Query)) + { + return new Dictionary(); + } + var queryStringNameValueCollection = HttpUtility.ParseQueryString(uri.Query); + return queryStringNameValueCollection.AllKeys.Where(k => k != null).ToDictionary(k => k, k => queryStringNameValueCollection[k]); } - var pairs = uri.Query.Substring(1).Split('&'); - foreach (var pair in pairs) + catch (Exception ex) { - var parts = pair.Split('='); - if (parts.Length < 1) - { - continue; - } - var key = System.Net.WebUtility.UrlDecode(parts[0]).ToLower(); - if (!dict.ContainsKey(key)) - { - dict.Add(key, parts[1] == null ? string.Empty : System.Net.WebUtility.UrlDecode(parts[1])); - } + LoggerHelper.LogEvenIfCantBeResolved(ex); } - return dict; + return new Dictionary(); } public static string SerializeJson(object obj, bool ignoreNulls = false) From f9a32e4abcedd490a518214a94e7aa3ab20315df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bispo?= Date: Mon, 26 Sep 2022 18:27:57 +0100 Subject: [PATCH 03/32] Passwordless feature branch PR (#2100) * [SG-471] Passwordless device login screen (#2017) * [SSG-471] Added UI for the device login request response. * [SG-471] Added text resources and arguments to Page. * [SG-471] Added properties to speed up page bindings * [SG-471] Added mock services. Added Accept/reject command binding, navigation and toast messages. * [SG-471] fixed code styling with dotnet-format * [SG-471] Fixed back button placement. PR fixes. * [SG-471] Added new Origin parameter to the page. * [SG-471] PR Fixes * [SG-471] PR fixes * [SG-471] PR Fix: added FireAndForget. * [SG-471] Moved fire and forget to run on ui thread task. * [SG-381] Passwordless - Add setting to Mobile (#2037) * [SG-381] Added settings option to approve passwordless login request. If user has notifications disabled, prompt to go to settings and enable them. * [SG-381] Update settings pop up texts. * [SG-381] Added new method to get notifications state on device settings. Added userId to property saved on device to differentiate value between users. * [SG-381] Added text for the popup on selection. * [SG-381] PR Fixes * [SG-408] Implement passwordless api methods (#2055) * [SG-408] Update notification model. * [SG-408] removed duplicated resource * [SG-408] Added implementation to Api Service of new passwordless methods. * removed qa endpoints * [SG-408] Changed auth methods implementation, added method call to viewmodel. * [SG-408] ran code format * [SG-408] PR fixes * [SG-472] Add configuration for new notification type (#2056) * [SG-472] Added methods to present local notification to the user. Configured new notification type for passwordless logins * [SG-472] Updated code to new api service changes. * [SG-472] ran dotnet format * [SG-472] PR Fixes. * [SG-472] PR Fixes * [SG-169] End-to-end testing refactor. (#2073) * [SG-169] Passwordless demo change requests (#2079) * [SG-169] End-to-end testing refactor. * [SG-169] Fixed labels. Changed color of Fingerprint phrase. Waited for app to be in foreground to launch passwordless modal to fix Android issues. * [SG-169] Anchored buttons to the bottom of the screen. * [SG-169] Changed device type from enum to string. * [SG-169] PR fixes * [SG-169] PR fixes * [SG-169] Added comment on static variable --- src/Android/MainActivity.cs | 21 +++ src/Android/Push/FirebaseMessagingService.cs | 39 +++--- .../AndroidPushNotificationService.cs | 38 ++++++ src/Android/Services/DeviceActionService.cs | 9 ++ src/App/Abstractions/IDeviceActionService.cs | 1 + .../Abstractions/IPushNotificationService.cs | 6 +- src/App/App.csproj | 3 + src/App/App.xaml.cs | 63 ++++++++- .../Pages/Accounts/LoginPasswordlessPage.xaml | 85 ++++++++++++ .../Accounts/LoginPasswordlessPage.xaml.cs | 31 +++++ .../Accounts/LoginPasswordlessViewModel.cs | 126 ++++++++++++++++++ .../SettingsPage/SettingsPageViewModel.cs | 43 +++++- src/App/Resources/AppResources.Designer.cs | 121 +++++++++++++++++ src/App/Resources/AppResources.resx | 60 +++++++++ .../Services/NoopPushNotificationService.cs | 12 +- .../PushNotificationListenerService.cs | 26 ++++ src/App/Styles/Black.xaml | 2 +- src/App/Styles/Dark.xaml | 2 +- src/App/Styles/Light.xaml | 2 +- src/App/Styles/Nord.xaml | 2 +- src/Core/Abstractions/IApiService.cs | 2 + src/Core/Abstractions/IAuthService.cs | 5 + src/Core/Abstractions/IStateService.cs | 5 + src/Core/Constants.cs | 4 + src/Core/Enums/NotificationType.cs | 7 + .../Request/PasswordlessLoginRequest.cs | 21 +++ .../Models/Response/NotificationResponse.cs | 6 + .../Response/PasswordlessLoginResponse.cs | 19 +++ src/Core/Services/ApiService.cs | 15 +++ src/Core/Services/AuthService.cs | 17 +++ src/Core/Services/StateService.cs | 34 +++++ src/iOS.Core/Services/DeviceActionService.cs | 6 + src/iOS/AppDelegate.cs | 2 +- .../Services/iOSPushNotificationHandler.cs | 1 - .../Services/iOSPushNotificationService.cs | 46 ++++++- 35 files changed, 852 insertions(+), 30 deletions(-) create mode 100644 src/App/Pages/Accounts/LoginPasswordlessPage.xaml create mode 100644 src/App/Pages/Accounts/LoginPasswordlessPage.xaml.cs create mode 100644 src/App/Pages/Accounts/LoginPasswordlessViewModel.cs create mode 100644 src/Core/Models/Request/PasswordlessLoginRequest.cs create mode 100644 src/Core/Models/Response/PasswordlessLoginResponse.cs diff --git a/src/Android/MainActivity.cs b/src/Android/MainActivity.cs index b5d5a0ff5..55eacba73 100644 --- a/src/Android/MainActivity.cs +++ b/src/Android/MainActivity.cs @@ -12,6 +12,7 @@ using Android.Runtime; using Android.Views; using Bit.App.Abstractions; using Bit.App.Models; +using Bit.App.Resources; using Bit.App.Utilities; using Bit.Core; using Bit.Core.Abstractions; @@ -86,6 +87,7 @@ namespace Bit.Droid Xamarin.Essentials.Platform.Init(this, savedInstanceState); Xamarin.Forms.Forms.Init(this, savedInstanceState); _appOptions = GetOptions(); + CreateNotificationChannel(); LoadApplication(new App.App(_appOptions)); DisableAndroidFontScale(); @@ -407,6 +409,25 @@ namespace Bit.Droid await _eventService.UploadEventsAsync(); } + private void CreateNotificationChannel() + { +#if !FDROID + if (Build.VERSION.SdkInt < BuildVersionCodes.O) + { + // Notification channels are new in API 26 (and not a part of the + // support library). There is no need to create a notification + // channel on older versions of Android. + return; + } + + var channel = new NotificationChannel(Constants.AndroidNotificationChannelId, AppResources.AllNotifications, NotificationImportance.Default); + if(GetSystemService(NotificationService) is NotificationManager notificationManager) + { + notificationManager.CreateNotificationChannel(channel); + } +#endif + } + private void DisableAndroidFontScale() { try diff --git a/src/Android/Push/FirebaseMessagingService.cs b/src/Android/Push/FirebaseMessagingService.cs index 676390aef..887c8ac44 100644 --- a/src/Android/Push/FirebaseMessagingService.cs +++ b/src/Android/Push/FirebaseMessagingService.cs @@ -1,7 +1,9 @@ #if !FDROID +using System; using Android.App; using Bit.App.Abstractions; using Bit.Core.Abstractions; +using Bit.Core.Services; using Bit.Core.Utilities; using Firebase.Messaging; using Newtonsoft.Json; @@ -16,34 +18,41 @@ namespace Bit.Droid.Push { public async override void OnNewToken(string token) { - var stateService = ServiceContainer.Resolve("stateService"); - var pushNotificationService = ServiceContainer.Resolve("pushNotificationService"); + try { + var stateService = ServiceContainer.Resolve("stateService"); + var pushNotificationService = ServiceContainer.Resolve("pushNotificationService"); - await stateService.SetPushRegisteredTokenAsync(token); - await pushNotificationService.RegisterAsync(); + await stateService.SetPushRegisteredTokenAsync(token); + await pushNotificationService.RegisterAsync(); + } + catch (Exception ex) + { + Logger.Instance.Exception(ex); + } } public async override void OnMessageReceived(RemoteMessage message) { - if (message?.Data == null) - { - return; - } - var data = message.Data.ContainsKey("data") ? message.Data["data"] : null; - if (data == null) - { - return; - } try { + if (message?.Data == null) + { + return; + } + var data = message.Data.ContainsKey("data") ? message.Data["data"] : null; + if (data == null) + { + return; + } + var obj = JObject.Parse(data); var listener = ServiceContainer.Resolve( "pushNotificationListenerService"); await listener.OnMessageAsync(obj, Device.Android); } - catch (JsonReaderException ex) + catch (Exception ex) { - System.Diagnostics.Debug.WriteLine(ex.ToString()); + Logger.Instance.Exception(ex); } } } diff --git a/src/Android/Services/AndroidPushNotificationService.cs b/src/Android/Services/AndroidPushNotificationService.cs index e871393f6..b8088cb80 100644 --- a/src/Android/Services/AndroidPushNotificationService.cs +++ b/src/Android/Services/AndroidPushNotificationService.cs @@ -1,8 +1,11 @@ #if !FDROID using System; using System.Threading.Tasks; +using Android.App; +using Android.Content; using AndroidX.Core.App; using Bit.App.Abstractions; +using Bit.Core; using Bit.Core.Abstractions; using Xamarin.Forms; @@ -23,6 +26,11 @@ namespace Bit.Droid.Services public bool IsRegisteredForPush => NotificationManagerCompat.From(Android.App.Application.Context)?.AreNotificationsEnabled() ?? false; + public Task AreNotificationsSettingsEnabledAsync() + { + return Task.FromResult(IsRegisteredForPush); + } + public async Task GetTokenAsync() { return await _stateService.GetPushCurrentTokenAsync(); @@ -47,6 +55,36 @@ namespace Bit.Droid.Services // Do we ever need to unregister? return Task.FromResult(0); } + + public void DismissLocalNotification(string notificationId) + { + if (int.TryParse(notificationId, out int intNotificationId)) + { + var notificationManager = NotificationManagerCompat.From(Android.App.Application.Context); + notificationManager.Cancel(intNotificationId); + } + } + + public void SendLocalNotification(string title, string message, string notificationId) + { + if (string.IsNullOrEmpty(notificationId)) + { + throw new ArgumentNullException("notificationId cannot be null or empty."); + } + + var context = Android.App.Application.Context; + var intent = new Intent(context, typeof(MainActivity)); + var pendingIntent = PendingIntent.GetActivity(context, 20220801, intent, PendingIntentFlags.UpdateCurrent); + var builder = new NotificationCompat.Builder(context, Constants.AndroidNotificationChannelId) + .SetContentIntent(pendingIntent) + .SetContentTitle(title) + .SetContentText(message) + .SetSmallIcon(Resource.Mipmap.ic_launcher) + .SetAutoCancel(true); + + var notificationManager = NotificationManagerCompat.From(context); + notificationManager.Notify(int.Parse(notificationId), builder.Build()); + } } } #endif diff --git a/src/Android/Services/DeviceActionService.cs b/src/Android/Services/DeviceActionService.cs index c981844ca..a66a3370c 100644 --- a/src/Android/Services/DeviceActionService.cs +++ b/src/Android/Services/DeviceActionService.cs @@ -964,5 +964,14 @@ namespace Bit.Droid.Services } activity.RunOnUiThread(() => activity.Window.AddFlags(WindowManagerFlags.Secure)); } + + public void OpenAppSettings() + { + var intent = new Intent(Android.Provider.Settings.ActionApplicationDetailsSettings); + intent.AddFlags(ActivityFlags.NewTask); + var uri = Android.Net.Uri.FromParts("package", Application.Context.PackageName, null); + intent.SetData(uri); + Application.Context.StartActivity(intent); + } } } diff --git a/src/App/Abstractions/IDeviceActionService.cs b/src/App/Abstractions/IDeviceActionService.cs index 1c7f75941..a314995f8 100644 --- a/src/App/Abstractions/IDeviceActionService.cs +++ b/src/App/Abstractions/IDeviceActionService.cs @@ -49,5 +49,6 @@ namespace Bit.App.Abstractions float GetSystemFontSizeScale(); Task OnAccountSwitchCompleteAsync(); Task SetScreenCaptureAllowedAsync(); + void OpenAppSettings(); } } diff --git a/src/App/Abstractions/IPushNotificationService.cs b/src/App/Abstractions/IPushNotificationService.cs index c4e3827cb..f0d56691e 100644 --- a/src/App/Abstractions/IPushNotificationService.cs +++ b/src/App/Abstractions/IPushNotificationService.cs @@ -1,12 +1,16 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; namespace Bit.App.Abstractions { public interface IPushNotificationService { bool IsRegisteredForPush { get; } + Task AreNotificationsSettingsEnabledAsync(); Task GetTokenAsync(); Task RegisterAsync(); Task UnregisterAsync(); + void SendLocalNotification(string title, string message, string notificationId); + void DismissLocalNotification(string notificationId); } } diff --git a/src/App/App.csproj b/src/App/App.csproj index 1c0e612d5..0a0eb15e6 100644 --- a/src/App/App.csproj +++ b/src/App/App.csproj @@ -123,6 +123,9 @@ Code + + LoginPasswordlessPage.xaml + diff --git a/src/App/App.xaml.cs b/src/App/App.xaml.cs index 6870f20f2..c83ab3308 100644 --- a/src/App/App.xaml.cs +++ b/src/App/App.xaml.cs @@ -7,6 +7,7 @@ using Bit.App.Resources; using Bit.App.Services; using Bit.App.Utilities; using Bit.App.Utilities.AccountManagement; +using Bit.Core; using Bit.Core.Abstractions; using Bit.Core.Enums; using Bit.Core.Models.Data; @@ -25,13 +26,13 @@ namespace Bit.App private readonly IStateService _stateService; private readonly IVaultTimeoutService _vaultTimeoutService; private readonly ISyncService _syncService; - private readonly IPlatformUtilsService _platformUtilsService; private readonly IAuthService _authService; - private readonly IStorageService _secureStorageService; private readonly IDeviceActionService _deviceActionService; private readonly IAccountsManager _accountsManager; - + private readonly IPushNotificationService _pushNotificationService; private static bool _isResumed; + // this variable is static because the app is launching new activities on notification click, creating new instances of App. + private static bool _pendingCheckPasswordlessLoginRequests; public App(AppOptions appOptions) { @@ -47,10 +48,9 @@ namespace Bit.App _vaultTimeoutService = ServiceContainer.Resolve("vaultTimeoutService"); _syncService = ServiceContainer.Resolve("syncService"); _authService = ServiceContainer.Resolve("authService"); - _platformUtilsService = ServiceContainer.Resolve("platformUtilsService"); - _secureStorageService = ServiceContainer.Resolve("secureStorageService"); _deviceActionService = ServiceContainer.Resolve("deviceActionService"); _accountsManager = ServiceContainer.Resolve("accountsManager"); + _pushNotificationService = ServiceContainer.Resolve(); _accountsManager.Init(() => Options, this); @@ -140,6 +140,10 @@ namespace Bit.App new NavigationPage(new RemoveMasterPasswordPage())); }); } + else if (message.Command == "passwordlessLoginRequest" || message.Command == "unlocked") + { + CheckPasswordlessLoginRequestsAsync().FireAndForget(); + } } catch (Exception ex) { @@ -148,11 +152,52 @@ namespace Bit.App }); } + private async Task CheckPasswordlessLoginRequestsAsync() + { + if (!_isResumed) + { + _pendingCheckPasswordlessLoginRequests = true; + return; + } + + _pendingCheckPasswordlessLoginRequests = false; + if (await _vaultTimeoutService.IsLockedAsync()) + { + return; + } + + + var notification = await _stateService.GetPasswordlessLoginNotificationAsync(); + if (notification == null) + { + return; + } + + // Delay to wait for the vault page to appear + await Task.Delay(2000); + var loginRequestData = await _authService.GetPasswordlessLoginRequestByIdAsync(notification.Id); + var page = new LoginPasswordlessPage(new LoginPasswordlessDetails() + { + PubKey = loginRequestData.PublicKey, + Id = loginRequestData.Id, + IpAddress = loginRequestData.RequestIpAddress, + Email = await _stateService.GetEmailAsync(), + FingerprintPhrase = loginRequestData.RequestFingerprint, + RequestDate = loginRequestData.CreationDate, + DeviceType = loginRequestData.RequestDeviceType, + Origin = loginRequestData.Origin, + }); + await _stateService.SetPasswordlessLoginNotificationAsync(null); + _pushNotificationService.DismissLocalNotification(Constants.PasswordlessNotificationId); + await Device.InvokeOnMainThreadAsync(async () => await Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page))); + } + public AppOptions Options { get; private set; } protected async override void OnStart() { System.Diagnostics.Debug.WriteLine("XF App: OnStart"); + _isResumed = true; await ClearCacheIfNeededAsync(); Prime(); if (string.IsNullOrWhiteSpace(Options.Uri)) @@ -164,6 +209,10 @@ namespace Bit.App SyncIfNeeded(); } } + if (_pendingCheckPasswordlessLoginRequests) + { + CheckPasswordlessLoginRequestsAsync().FireAndForget(); + } if (Device.RuntimePlatform == Device.Android) { await _vaultTimeoutService.CheckVaultTimeoutAsync(); @@ -196,6 +245,10 @@ namespace Bit.App { System.Diagnostics.Debug.WriteLine("XF App: OnResume"); _isResumed = true; + if (_pendingCheckPasswordlessLoginRequests) + { + CheckPasswordlessLoginRequestsAsync().FireAndForget(); + } if (Device.RuntimePlatform == Device.Android) { ResumedAsync().FireAndForget(); diff --git a/src/App/Pages/Accounts/LoginPasswordlessPage.xaml b/src/App/Pages/Accounts/LoginPasswordlessPage.xaml new file mode 100644 index 000000000..83361c29c --- /dev/null +++ b/src/App/Pages/Accounts/LoginPasswordlessPage.xaml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + +