diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index 0c117fded02..916f765ea21 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -338,7 +338,7 @@ "message": "Pokračovat na bitwarden.com?" }, "bitwardenForBusiness": { - "message": "Bitwarden pro byznys" + "message": "Bitwarden pro podnikání" }, "bitwardenAuthenticator": { "message": "Autentifikátor Bitwarden" @@ -398,7 +398,7 @@ "message": "Název složky" }, "folderHintText": { - "message": "Vnořit složku přidáním názvu nadřazené složky následovaného znakem \"/\". Příklad: Sociální/Fóra" + "message": "Složku vnoříte přidáním názvu nadřazené složky následovaného znakem \"/\". Příklad: Sociální/Fóra" }, "noFoldersAdded": { "message": "Nebyly přidány žádné složky" @@ -407,7 +407,7 @@ "message": "Vytvořte složky pro organizaci Vašich položek trezoru" }, "deleteFolderPermanently": { - "message": "Opravdu chcete trvale smazat tuto složku?" + "message": "Opravdu chcete tuto složku trvale smazat?" }, "deleteFolder": { "message": "Smazat složku" @@ -531,10 +531,10 @@ "message": "Zahrnout číslice" }, "minNumbers": { - "message": "Minimální počet číslic" + "message": "Minimálně číslic" }, "minSpecial": { - "message": "Minimální počet speciálních znaků" + "message": "Minimálně speciálních znaků" }, "avoidAmbiguous": { "message": "Nepoužívat zaměnitelné znaky", @@ -1016,7 +1016,7 @@ "description": "This is the folder for uncategorized items" }, "enableAddLoginNotification": { - "message": "Ptát se na přidání přihlášení" + "message": "Zeptat se na přidání přihlášení" }, "vaultSaveOptionsTitle": { "message": "Uložit do voleb trezoru" @@ -1049,7 +1049,7 @@ "message": "Klepněte na položky pro automatické vyplnění v zobrazení trezoru" }, "clickToAutofill": { - "message": "Klepněte na položky v návrhu automatického vyplňování pro vyplnění" + "message": "Klepnout na položky v návrhu automatického vyplňování pro vyplnění" }, "clearClipboard": { "message": "Vymazat schránku", @@ -1305,7 +1305,7 @@ "message": "Sdílené" }, "bitwardenForBusinessPageDesc": { - "message": "Bitwarden pro bvyznys Vám umožňuje sdílet položky v trezoru s ostatními prostřednictvím organizace. Více informací naleznete na bitwarden.com." + "message": "Bitwarden pro podnikání Vám umožňuje sdílet položky v trezoru s ostatními prostřednictvím organizace. Více informací naleznete na bitwarden.com." }, "moveToOrganization": { "message": "Přesunout do organizace" @@ -1660,7 +1660,7 @@ "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, "enableAutoFillOnPageLoadSectionTitle": { - "message": "Automaticky vyplnit údaje při načtení stránky" + "message": "Automatické vyplnění údajů při načtení stránky" }, "enableAutoFillOnPageLoad": { "message": "Automaticky vyplnit údaje při načtení stránky" @@ -1678,7 +1678,7 @@ "message": "Více informací o automatickém vyplňování" }, "defaultAutoFillOnPageLoad": { - "message": "Výchozí nastavení automatického vyplňování pro položky přihlášení" + "message": "Výchozí nastavení autom. vyplňování" }, "defaultAutoFillOnPageLoadDesc": { "message": "Můžete vypnout automatické vyplňování při načtení stránky pro jednotlivé přihlašovací položky v zobrazení pro úpravu položky." @@ -1690,10 +1690,10 @@ "message": "Použít výchozí nastavení" }, "autoFillOnPageLoadYes": { - "message": "Automatické vyplnění při načtení stránky" + "message": "Automatické vyplnění při načtení" }, "autoFillOnPageLoadNo": { - "message": "Nevyplňovat automaticky při načtení stránky" + "message": "Nevyplňovat automaticky při načtení" }, "commandOpenPopup": { "message": "Otevřít vyskakovací okno trezoru" @@ -1851,7 +1851,7 @@ "message": "Slečna" }, "dr": { - "message": "MUDr." + "message": "Dr." }, "mx": { "message": "Neutrální" @@ -1875,7 +1875,7 @@ "message": "Společnost" }, "ssn": { - "message": "Číslo sociálního pojištění" + "message": "Rodné číslo" }, "passportNumber": { "message": "Číslo cestovního pasu" @@ -2099,7 +2099,7 @@ "message": "Nic k zobrazení" }, "nothingGeneratedRecently": { - "message": "Nedávno jste nic nevygenerovali" + "message": "Ještě jste nic nevygenerovali" }, "remove": { "message": "Odebrat" @@ -2233,7 +2233,7 @@ "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "useGeneratorHelpTextPartTwo": { - "message": "pro vytvoření silného jedinečného hesla", + "message": "pro vytvoření silného jedinečného hesla.", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "vaultCustomization": { @@ -2685,7 +2685,7 @@ "message": "Změny v zablokovaných doménách byly uloženy" }, "excludedDomainsSavedSuccess": { - "message": "Vyloučené změny domény byly uloženy" + "message": "Změny vyloučené domény byly uloženy" }, "limitSendViews": { "message": "Omezit zobrazení" @@ -2911,7 +2911,7 @@ "message": "Došlo k chybě při ukládání datumu smzání a vypršení platnosti." }, "hideYourEmail": { - "message": "Skryje Vaši e-mailovou adresu před zobrazením." + "message": "Skrýt Vaši e-mailovou adresu" }, "passwordPrompt": { "message": "Zeptat se znovu na hlavní heslo" @@ -3228,7 +3228,7 @@ "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { - "message": "Vyberte doménu, která je podporována vybranou službou", + "message": "Vyberte doménu, která je podporována vybranou službou.", "description": "Guidance provided for email forwarding services that support multiple email domains." }, "forwarderError": { @@ -4132,7 +4132,7 @@ "message": "Zvolte sbírku" }, "importTargetHint": { - "message": "Pokud chcete obsah importovaného souboru přesunout do složky $DESTINATION$, vyberte tuto volbu", + "message": "Pokud chcete obsah importovaného souboru přesunout do: \"$DESTINATION$\", vyberte tuto volbu", "description": "Located as a hint under the import target. Will be appended by either folder or collection, depending if the user is importing into an individual or an organizational vault.", "placeholders": { "destination": { @@ -4407,7 +4407,7 @@ "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" }, "confirmContinueToHelpCenterPasswordManagementContent": { - "message": "Změňte nastavení automatického vyplňování a správy hesel.", + "message": "Změna nastavení automatického vyplňování a nastavení správy hesel.", "description": "Body content for dialog which asks if the user wants to proceed to the Help Center's page about browser password management settings" }, "confirmContinueToHelpCenterKeyboardShortcutsContent": { @@ -4415,7 +4415,7 @@ "description": "Body content for dialog which asks if the user wants to proceed to the Help Center's page about browser keyboard shortcut settings" }, "confirmContinueToBrowserPasswordManagementSettingsContent": { - "message": "Změňte nastavení automatického vyplňování a správy hesel.", + "message": "Změna nastavení automatického vyplňování a nastavení správy hesel.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" }, "confirmContinueToBrowserKeyboardShortcutSettingsContent": { @@ -4945,13 +4945,13 @@ "message": "Popis pole" }, "textHelpText": { - "message": "Použijte textová pole pro data jako bezpečnostní otázky" + "message": "Použijte textová pole pro data (jako např. bezpečnostní otázky)." }, "hiddenHelpText": { - "message": "Použijte skrytá pole pro citlivá data, jako je heslo" + "message": "Použijte skrytá pole pro citlivá data, jako je heslo." }, "checkBoxHelpText": { - "message": "Použijte zaškrtávací políčka, pokud chcete automaticky vyplnit zaškrtávací políčko formuláře (např. pro zapamatování e-mailu)" + "message": "Použijte zaškrtávací políčka, pokud chcete automaticky zvolit zaškrtávací políčko formuláře (např. pro zapamatování e-mailu)." }, "linkedHelpText": { "message": "Použijte propojené pole, pokud máte problémy s automatickým vyplňováním na konkrétní webové stránce." @@ -5121,7 +5121,7 @@ "message": "Zobrazit akce rychlé kopie v trezoru" }, "systemDefault": { - "message": "Systémový výchozí" + "message": "Výchozí systémový" }, "enterprisePolicyRequirementsApplied": { "message": "Na toto nastavení byly uplatněny požadavky podnikových zásad" @@ -5178,7 +5178,7 @@ "message": "Položky, které smažete, se zde zobrazí a budou trvale smazány po 30 dnech." }, "trashWarning": { - "message": "Položky, které byly v koši déle než 30 dní, budou automaticky smazány." + "message": "Položky, které byly v koši déle než 30 dnů, budou automaticky smazány." }, "restore": { "message": "Obnovit" @@ -5394,10 +5394,10 @@ "message": "Šířka rozšíření" }, "wide": { - "message": "Šířka" + "message": "Široké" }, "extraWide": { - "message": "Extra široký" + "message": "Extra široké" }, "sshKeyWrongPassword": { "message": "Zadané heslo není správné." diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index 4ce77543a45..3d46b63ec45 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -84,7 +84,7 @@ "message": "Υπόδειξη κύριου κωδικού πρόσβασης (προαιρετικό)" }, "passwordStrengthScore": { - "message": "Password strength score $SCORE$", + "message": "Βαθμολογία ισχύς κωδικού πρόσβασης $SCORE$", "placeholders": { "score": { "content": "$1", @@ -468,13 +468,13 @@ "message": "Ο κωδικός δημιουργήθηκε" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "Το συνθηματικό δημιουργήθηκε" }, "usernameGenerated": { - "message": "Username generated" + "message": "Το όνομα χρήστη δημιουργήθηκε" }, "emailGenerated": { - "message": "Email generated" + "message": "Το email δημιουργήθηκε" }, "regeneratePassword": { "message": "Επαναδημιουργία κωδικού πρόσβασης" @@ -548,7 +548,7 @@ "message": "Αναζήτηση στο vault" }, "resetSearch": { - "message": "Reset search" + "message": "Επαναφορά αναζήτησης" }, "edit": { "message": "Επεξεργασία" @@ -659,10 +659,10 @@ "message": "Το πρόγραμμα περιήγησης ιστού δεν υποστηρίζει εύκολη αντιγραφή πρόχειρου. Αντιγράψτε το με το χέρι αντ'αυτού." }, "verifyYourIdentity": { - "message": "Verify your identity" + "message": "Επαλήθευση ταυτότητας" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "Δεν αναγνωρίζουμε αυτή τη συσκευή. Εισάγετε τον κωδικό που στάλθηκε στο email σας για να επαληθεύσετε την ταυτότητά σας." }, "continueLoggingIn": { "message": "Continue logging in" @@ -875,22 +875,22 @@ "message": "Σύνδεση στο Bitwarden" }, "enterTheCodeSentToYourEmail": { - "message": "Enter the code sent to your email" + "message": "Εισάγετε τον κωδικό που στάλθηκε στο email σας" }, "enterTheCodeFromYourAuthenticatorApp": { - "message": "Enter the code from your authenticator app" + "message": "Εισαγάγετε τον κωδικό μιας χρήσης από την εφαρμογή αυθεντικοποίησης" }, "pressYourYubiKeyToAuthenticate": { - "message": "Press your YubiKey to authenticate" + "message": "Πιέστε το YubiKey σας για ταυτοποίηση" }, "duoTwoFactorRequiredPageSubtitle": { - "message": "Duo two-step login is required for your account. Follow the steps below to finish logging in." + "message": "Απαιτείται σύνδεση Duo δύο βημάτων για το λογαριασμό σας. Ακολουθήστε τα παρακάτω βήματα για να ολοκληρώσετε τη σύνδεση." }, "followTheStepsBelowToFinishLoggingIn": { - "message": "Follow the steps below to finish logging in." + "message": "Ακολουθήστε τα παρακάτω βήματα για να ολοκληρώσετε τη σύνδεση." }, "followTheStepsBelowToFinishLoggingInWithSecurityKey": { - "message": "Follow the steps below to finish logging in with your security key." + "message": "Ακολουθήστε τα παρακάτω βήματα για να ολοκληρώσετε τη σύνδεση με το κλειδί ασφαλείας σας." }, "restartRegistration": { "message": "Επανεκκίνηση εγγραφής" diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index 1a304a94d48..d38461ab553 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -5575,9 +5575,9 @@ "description": "'WebAssembly' is a technical term and should not be translated." }, "showMore": { - "message": "Show more" + "message": "Prikaži više" }, "showLess": { - "message": "Show less" + "message": "Pokaži manje" } } diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 89f502c5e49..68d5a0db2e3 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -605,7 +605,7 @@ "message": "Izdzēst vienumu" }, "viewItem": { - "message": "Skatīt vienumu" + "message": "Apskatīt vienumu" }, "launch": { "message": "Palaist" @@ -1180,7 +1180,7 @@ "message": "Pēc savas paroles nomainīšanas būs nepieciešams pieteikties ar jauno paroli. Spēkā esošajās sesijās citās ierīcēs stundas laikā notiks atteikšanās." }, "accountRecoveryUpdateMasterPasswordSubtitle": { - "message": "Jānomaina sava galvenā'parole, lai pabeigtu konta atkopi." + "message": "Jānomaina sava galvenā parole, lai pabeigtu konta atkopi." }, "enableChangedPasswordNotification": { "message": "Vaicāt atjaunināt esošu pieteikšanās vienumu" @@ -1490,7 +1490,7 @@ "description": "Select another two-step login method" }, "useYourRecoveryCode": { - "message": "Izmantot savu atkopes kodu" + "message": "Izmanto savu atkopes kodu" }, "insertU2f": { "message": "Ievieto savu drošības atslēgu datora USB ligzdā! Ja tai ir poga, pieskaries tai!" @@ -1523,10 +1523,10 @@ "message": "Atlasīt divpakāpju pieteikšanās veidu" }, "recoveryCodeDesc": { - "message": "Zaudēta piekļuve visiem divpakāpju nodrošinātājiem? Izmanto atkopšanas kodus, lai atspējotu visus sava konta divpakāpju nodrošinātājus!" + "message": "Zaudēta piekļuve visiem divpakāpju nodrošinātājiem? Izmanto atkopes kodus, lai atspējotu visus sava konta divpakāpju nodrošinātājus!" }, "recoveryCodeTitle": { - "message": "Atgūšanas kods" + "message": "Atkopes kods" }, "authenticatorAppTitle": { "message": "Autentificētāja lietotne" @@ -3437,7 +3437,7 @@ "message": "Atkārtoti nosūtīt paziņojumu" }, "viewAllLogInOptions": { - "message": "Skatīt visas pieteikšanās iespējas" + "message": "Apskatīt visas pieteikšanās iespējas" }, "notificationSentDevice": { "message": "Uz ierīci ir nosūtīts paziņojums." @@ -3728,7 +3728,7 @@ "description": "European Union" }, "accessDenied": { - "message": "Piekļuve liegta. Nav nepieciešamo atļauju, lai skatītu šo lapu." + "message": "Piekļuve liegta. Nav nepieciešamo atļauju, lai apskatītu šo lapu." }, "general": { "message": "Vispārīgi" @@ -4387,7 +4387,7 @@ "description": "Content for dialog which warns a user when selecting 'regular expression' matching strategy as a cipher match strategy" }, "startsWithAdvancedOptionWarning": { - "message": "\"Sākas ar' ir lietpratējiem paredzēta iespēja ar paaugstinātu piekļuves datu atklāšanas bīstamību.", + "message": "“Sākas ar” ir lietpratējiem paredzēta iespēja ar paaugstinātu piekļuves datu atklāšanas bīstamību.", "description": "Content for dialog which warns a user when selecting 'starts with' matching strategy as a cipher match strategy" }, "uriMatchWarningDialogLink": { @@ -4411,7 +4411,7 @@ "description": "Body content for dialog which asks if the user wants to proceed to the Help Center's page about browser password management settings" }, "confirmContinueToHelpCenterKeyboardShortcutsContent": { - "message": "Paplašinājuma īsinājumtaustiņus skatīt un iestatīt var pārlūka iestatījumos.", + "message": "Paplašinājuma īsinājumtaustiņus apskatīt un iestatīt var pārlūka iestatījumos.", "description": "Body content for dialog which asks if the user wants to proceed to the Help Center's page about browser keyboard shortcut settings" }, "confirmContinueToBrowserPasswordManagementSettingsContent": { @@ -4419,7 +4419,7 @@ "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" }, "confirmContinueToBrowserKeyboardShortcutSettingsContent": { - "message": "Paplašinājuma īsinājumtaustiņus skatīt un iestatīt var pārlūka iestatījumos.", + "message": "Paplašinājuma īsinājumtaustiņus apskatīt un iestatīt var pārlūka iestatījumos.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" }, "overrideDefaultBrowserAutofillTitle": { @@ -4534,7 +4534,7 @@ } }, "viewItemTitle": { - "message": "Skatīt vienumu - $ITEMNAME$", + "message": "Apskatīt vienumu - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4629,7 +4629,7 @@ "message": "Kļūda mērķa mapes piešķiršanā." }, "viewItemsIn": { - "message": "Skatīt $NAME$ vienumus", + "message": "Apskatīt $NAME$ vienumus", "description": "Button to view the contents of a folder or collection", "placeholders": { "name": { diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index 6e1029c613d..97875409529 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -1153,7 +1153,7 @@ "description": "Shown to user after login is updated." }, "loginUpdateTaskSuccessAdditional": { - "message": "Dziękujemy za dbanie o bezpieczeństwo $ORGANIZATION$. Pozostało $TASK_COUNT$ haseł do zaktualizowania.", + "message": "Dziękujemy za zwiększenie bezpieczeństwa organizacji $ORGANIZATION$. Zaktualizuj hasła dla jeszcze $TASK_COUNT$ danych logowania.", "placeholders": { "organization": { "content": "$1" @@ -1773,7 +1773,7 @@ "message": "Pokaż licznik na ikonie" }, "badgeCounterDesc": { - "message": "Wskaż, ile masz danych logowania do bieżącej strony internetowej." + "message": "Pokazuje liczbę danych logowania dla obecnej strony internetowej." }, "cardholderName": { "message": "Właściciel karty" @@ -2482,7 +2482,7 @@ "message": "Uprawnienie nie zostało przyznane" }, "nativeMessaginPermissionErrorDesc": { - "message": "Bez uprawnienia do komunikowania się z aplikacją desktopową Bitwarden nie możemy dostarczyć obsługi danych biometrycznych w rozszerzeniu przeglądarki. Spróbuj ponownie." + "message": "Odblokowanie biometrią jest dostępne dopiero po połączeniu rozszerzenia przeglądarki z aplikacją desktopową Bitwarden. Spróbuj ponownie." }, "nativeMessaginPermissionSidebarTitle": { "message": "Wystąpił błąd żądania uprawnienia" @@ -2610,7 +2610,7 @@ "message": "Sprawdź i zmień 1 zagrożone hasło" }, "reviewAndChangeAtRiskPasswordsPlural": { - "message": "Przejrzyj i zmień $COUNT$ zagrożonych haseł ", + "message": "Sprawdź i zmień zagrożone hasła ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -3380,7 +3380,7 @@ "message": "Nie można uzyskać dostępu do elementów w zawieszonych organizacjach. Skontaktuj się z właścicielem organizacji, aby uzyskać pomoc." }, "loggingInTo": { - "message": "Logowanie na $DOMAIN$", + "message": "Serwer: $DOMAIN$", "placeholders": { "domain": { "content": "$1", @@ -4354,7 +4354,7 @@ "message": "serwer" }, "hostedAt": { - "message": "hostowany w" + "message": "serwer" }, "useDeviceOrHardwareKey": { "message": "Użyj urządzenia lub klucza sprzętowego" @@ -5025,7 +5025,7 @@ "message": "Element zostanie przeniesiony do organizacji. Nie będziesz już właścicielem elementu." }, "personalItemsTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ elementów zostanie trwale przeniesionych do wybranej organizacji. Nie będziesz już posiadać tych elementów.", + "message": "Nie będziesz już właścicielem $PERSONAL_ITEMS_COUNT$ elementów przeniesionych do organizacji.", "placeholders": { "personal_items_count": { "content": "$1", @@ -5043,7 +5043,7 @@ } }, "personalItemsWithOrgTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ elementy zostaną trwale przeniesione do $ORG$. Nie będziesz już posiadać tych elementów.", + "message": "Nie będziesz już właścicielem $PERSONAL_ITEMS_COUNT$ elementów przeniesionych do organizacji $ORG$.", "placeholders": { "personal_items_count": { "content": "$1", diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index aa926ac77b8..d3ce5ec3e48 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -4383,7 +4383,7 @@ "description": "Explains to the user that URI match detection determines how Bitwarden suggests autofill options, and clarifies that this default strategy applies when no specific match detection is set for a login item." }, "regExAdvancedOptionWarning": { - "message": "A \"expressão regular\" é uma opção avançada com um risco acrescido de exposição de credenciais.", + "message": "A \"Expressão regular\" é uma opção avançada com um risco acrescido de exposição de credenciais.", "description": "Content for dialog which warns a user when selecting 'regular expression' matching strategy as a cipher match strategy" }, "startsWithAdvancedOptionWarning": { diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index 641205fffb7..7a596d7c23d 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -1836,7 +1836,7 @@ "message": "số thẻ" }, "ex": { - "message": "Ví dụ:" + "message": "ví dụ." }, "title": { "message": "Tiêu đề" @@ -2458,7 +2458,7 @@ "message": "Nhận dạng sinh trắc học không được hỗ trợ" }, "biometricsNotSupportedDesc": { - "message": "Nhận dạng sinh trắc học trên trình duyệt không được hỗ trợ trên thiết bị này" + "message": "Nhận dạng sinh trắc học trên trình duyệt không được hỗ trợ trên thiết bị này." }, "biometricsNotUnlockedTitle": { "message": "Người dùng đã khoá hoặc đã đăng xuất" diff --git a/apps/browser/src/autofill/background/abstractions/notification.background.ts b/apps/browser/src/autofill/background/abstractions/notification.background.ts index 571d9fbaf5f..cc28ed0057e 100644 --- a/apps/browser/src/autofill/background/abstractions/notification.background.ts +++ b/apps/browser/src/autofill/background/abstractions/notification.background.ts @@ -4,11 +4,29 @@ import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { CollectionView } from "../../content/components/common-types"; -import { NotificationQueueMessageTypes } from "../../enums/notification-queue-message-type.enum"; +import { NotificationType, NotificationTypes } from "../../enums/notification-type.enum"; import AutofillPageDetails from "../../models/autofill-page-details"; +/** + * @todo Remove Standard_ label when implemented as standard NotificationQueueMessage. + */ +export interface Standard_NotificationQueueMessage { + // universal notification properties + domain: string; + tab: chrome.tabs.Tab; + launchTimestamp: number; + expires: Date; + wasVaultLocked: boolean; + + type: T; // NotificationType + data: D; // notification-specific data +} + +/** + * @todo Deprecate in favor of Standard_NotificationQueueMessage. + */ interface NotificationQueueMessage { - type: NotificationQueueMessageTypes; + type: NotificationTypes; domain: string; tab: chrome.tabs.Tab; launchTimestamp: number; @@ -16,11 +34,15 @@ interface NotificationQueueMessage { wasVaultLocked: boolean; } -interface AddChangePasswordQueueMessage extends NotificationQueueMessage { - type: "change"; +type ChangePasswordNotificationData = { cipherId: CipherView["id"]; newPassword: string; -} +}; + +type AddChangePasswordNotificationQueueMessage = Standard_NotificationQueueMessage< + typeof NotificationType.ChangePassword, + ChangePasswordNotificationData +>; interface AddLoginQueueMessage extends NotificationQueueMessage { type: "add"; @@ -41,7 +63,7 @@ interface AtRiskPasswordQueueMessage extends NotificationQueueMessage { type NotificationQueueMessageItem = | AddLoginQueueMessage - | AddChangePasswordQueueMessage + | AddChangePasswordNotificationQueueMessage | AddUnlockVaultQueueMessage | AtRiskPasswordQueueMessage; @@ -72,6 +94,11 @@ type UnlockVaultMessageData = { skipNotification?: boolean; }; +/** + * @todo Extend generics to this type, see Standard_NotificationQueueMessage + * - use new `data` types as generic + * - eliminate optional status of properties as needed per Notification Type + */ type NotificationBackgroundExtensionMessage = { [key: string]: any; command: string; @@ -126,7 +153,7 @@ type NotificationBackgroundExtensionMessageHandlers = { }; export { - AddChangePasswordQueueMessage, + AddChangePasswordNotificationQueueMessage, AddLoginQueueMessage, AddUnlockVaultQueueMessage, NotificationQueueMessageItem, diff --git a/apps/browser/src/autofill/background/notification.background.spec.ts b/apps/browser/src/autofill/background/notification.background.spec.ts index 7302ae7d705..1c72b2af1d1 100644 --- a/apps/browser/src/autofill/background/notification.background.spec.ts +++ b/apps/browser/src/autofill/background/notification.background.spec.ts @@ -26,14 +26,14 @@ import { FolderService } from "@bitwarden/common/vault/services/folder/folder.se import { TaskService, SecurityTask } from "@bitwarden/common/vault/tasks"; import { BrowserApi } from "../../platform/browser/browser-api"; -import { NotificationQueueMessageType } from "../enums/notification-queue-message-type.enum"; +import { NotificationType } from "../enums/notification-type.enum"; import { FormData } from "../services/abstractions/autofill.service"; import AutofillService from "../services/autofill.service"; import { createAutofillPageDetailsMock, createChromeTabMock } from "../spec/autofill-mocks"; import { flushPromises, sendMockExtensionMessage } from "../spec/testing-utils"; import { - AddChangePasswordQueueMessage, + AddChangePasswordNotificationQueueMessage, AddLoginQueueMessage, AddUnlockVaultQueueMessage, LockedVaultPendingNotificationsData, @@ -761,7 +761,7 @@ describe("NotificationBackground", () => { notificationBackground["notificationQueue"] = [ mock({ tab, - type: NotificationQueueMessageType.UnlockVault, + type: NotificationType.UnlockVault, }), ]; @@ -783,7 +783,7 @@ describe("NotificationBackground", () => { }; notificationBackground["notificationQueue"] = [ mock({ - type: NotificationQueueMessageType.AddLogin, + type: NotificationType.AddLogin, tab, domain: "another.com", }), @@ -803,11 +803,11 @@ describe("NotificationBackground", () => { edit: false, folder: "folder-id", }; - const queueMessage = mock({ - type: NotificationQueueMessageType.ChangePassword, + const queueMessage = mock({ + type: NotificationType.ChangePassword, tab, domain: "example.com", - newPassword: "newPassword", + data: { newPassword: "newPassword" }, }); notificationBackground["notificationQueue"] = [queueMessage]; const cipherView = mock({ @@ -825,7 +825,7 @@ describe("NotificationBackground", () => { expect(createWithServerSpy).not.toHaveBeenCalled(); expect(updatePasswordSpy).toHaveBeenCalledWith( cipherView, - queueMessage.newPassword, + queueMessage.data.newPassword, message.edit, sender.tab, "testId", @@ -851,11 +851,11 @@ describe("NotificationBackground", () => { edit: false, folder: "folder-id", }; - const queueMessage = mock({ - type: NotificationQueueMessageType.ChangePassword, + const queueMessage = mock({ + type: NotificationType.ChangePassword, tab, domain: "example.com", - newPassword: "newPassword", + data: { newPassword: "newPassword" }, }); notificationBackground["notificationQueue"] = [queueMessage]; const cipherView = mock({ @@ -874,7 +874,7 @@ describe("NotificationBackground", () => { expect(createWithServerSpy).not.toHaveBeenCalled(); expect(updatePasswordSpy).toHaveBeenCalledWith( cipherView, - queueMessage.newPassword, + queueMessage.data.newPassword, message.edit, sender.tab, "testId", @@ -931,11 +931,11 @@ describe("NotificationBackground", () => { edit: false, folder: "folder-id", }; - const queueMessage = mock({ - type: NotificationQueueMessageType.ChangePassword, + const queueMessage = mock({ + type: NotificationType.ChangePassword, tab, domain: "example.com", - newPassword: "newPassword", + data: { newPassword: "newPassword" }, }); notificationBackground["notificationQueue"] = [queueMessage]; const cipherView = mock({ @@ -953,7 +953,7 @@ describe("NotificationBackground", () => { expect(createWithServerSpy).not.toHaveBeenCalled(); expect(updatePasswordSpy).toHaveBeenCalledWith( cipherView, - queueMessage.newPassword, + queueMessage.data.newPassword, message.edit, sender.tab, mockCipherId, @@ -983,7 +983,7 @@ describe("NotificationBackground", () => { folder: "folder-id", }; const queueMessage = mock({ - type: NotificationQueueMessageType.AddLogin, + type: NotificationType.AddLogin, tab, domain: "example.com", username: "test", @@ -1018,11 +1018,11 @@ describe("NotificationBackground", () => { edit: true, folder: "folder-id", }; - const queueMessage = mock({ - type: NotificationQueueMessageType.ChangePassword, + const queueMessage = mock({ + type: NotificationType.ChangePassword, tab, domain: "example.com", - newPassword: "newPassword", + data: { newPassword: "newPassword" }, }); notificationBackground["notificationQueue"] = [queueMessage]; const cipherView = mock(); @@ -1035,7 +1035,7 @@ describe("NotificationBackground", () => { expect(updatePasswordSpy).toHaveBeenCalledWith( cipherView, - queueMessage.newPassword, + queueMessage.data.newPassword, message.edit, sender.tab, "testId", @@ -1070,7 +1070,7 @@ describe("NotificationBackground", () => { folder: "folder-id", }; const queueMessage = mock({ - type: NotificationQueueMessageType.AddLogin, + type: NotificationType.AddLogin, tab, domain: "example.com", username: "test", @@ -1109,7 +1109,7 @@ describe("NotificationBackground", () => { folder: "folder-id", }; const queueMessage = mock({ - type: NotificationQueueMessageType.AddLogin, + type: NotificationType.AddLogin, tab, domain: "example.com", username: "test", @@ -1162,7 +1162,7 @@ describe("NotificationBackground", () => { folder: "folder-id", }; const queueMessage = mock({ - type: NotificationQueueMessageType.AddLogin, + type: NotificationType.AddLogin, tab, domain: "example.com", username: "test", @@ -1213,11 +1213,11 @@ describe("NotificationBackground", () => { edit: false, folder: "folder-id", }; - const queueMessage = mock({ - type: NotificationQueueMessageType.ChangePassword, + const queueMessage = mock({ + type: NotificationType.ChangePassword, tab, domain: "example.com", - newPassword: "newPassword", + data: { newPassword: "newPassword" }, }); notificationBackground["notificationQueue"] = [queueMessage]; const cipherView = mock({ reprompt: CipherRepromptType.None }); @@ -1273,7 +1273,7 @@ describe("NotificationBackground", () => { const sender = mock({ tab }); const message: NotificationBackgroundExtensionMessage = { command: "bgNeverSave" }; notificationBackground["notificationQueue"] = [ - mock({ type: NotificationQueueMessageType.UnlockVault, tab }), + mock({ type: NotificationType.UnlockVault, tab }), ]; sendMockExtensionMessage(message, sender); @@ -1289,7 +1289,7 @@ describe("NotificationBackground", () => { const sender = mock({ tab: secondaryTab }); notificationBackground["notificationQueue"] = [ mock({ - type: NotificationQueueMessageType.AddLogin, + type: NotificationType.AddLogin, tab, domain: "another.com", }), @@ -1306,12 +1306,12 @@ describe("NotificationBackground", () => { const sender = mock({ tab }); const message: NotificationBackgroundExtensionMessage = { command: "bgNeverSave" }; const firstNotification = mock({ - type: NotificationQueueMessageType.AddLogin, + type: NotificationType.AddLogin, tab, domain: "example.com", }); const secondNotification = mock({ - type: NotificationQueueMessageType.AddLogin, + type: NotificationType.AddLogin, tab: createChromeTabMock({ id: 3 }), domain: "another.com", }); diff --git a/apps/browser/src/autofill/background/notification.background.ts b/apps/browser/src/autofill/background/notification.background.ts index 3f6e93d8454..e9eea552f37 100644 --- a/apps/browser/src/autofill/background/notification.background.ts +++ b/apps/browser/src/autofill/background/notification.background.ts @@ -60,12 +60,12 @@ import { NotificationCipherData, } from "../content/components/cipher/types"; import { CollectionView } from "../content/components/common-types"; -import { NotificationQueueMessageType } from "../enums/notification-queue-message-type.enum"; +import { NotificationType } from "../enums/notification-type.enum"; import { AutofillService } from "../services/abstractions/autofill.service"; import { TemporaryNotificationChangeLoginService } from "../services/notification-change-login-password.service"; import { - AddChangePasswordQueueMessage, + AddChangePasswordNotificationQueueMessage, AddLoginQueueMessage, AddUnlockVaultQueueMessage, AddLoginMessageData, @@ -208,16 +208,21 @@ export default class NotificationBackground { organizations.find((org) => org.id === orgId)?.productTierType; const cipherQueueMessage = this.notificationQueue.find( - (message): message is AddChangePasswordQueueMessage | AddLoginQueueMessage => - message.type === NotificationQueueMessageType.ChangePassword || - message.type === NotificationQueueMessageType.AddLogin, + (message): message is AddChangePasswordNotificationQueueMessage | AddLoginQueueMessage => + message.type === NotificationType.ChangePassword || + message.type === NotificationType.AddLogin, ); if (cipherQueueMessage) { - const cipherView = - cipherQueueMessage.type === NotificationQueueMessageType.ChangePassword - ? await this.getDecryptedCipherById(cipherQueueMessage.cipherId, activeUserId) - : this.convertAddLoginQueueMessageToCipherView(cipherQueueMessage); + let cipherView: CipherView; + if (cipherQueueMessage.type === NotificationType.ChangePassword) { + const { + data: { cipherId }, + } = cipherQueueMessage; + cipherView = await this.getDecryptedCipherById(cipherId, activeUserId); + } else { + cipherView = this.convertAddLoginQueueMessageToCipherView(cipherQueueMessage); + } const organizationType = getOrganizationType(cipherView.organizationId); return [ @@ -424,7 +429,7 @@ export default class NotificationBackground { }; switch (notificationType) { - case NotificationQueueMessageType.AddLogin: + case NotificationType.AddLogin: typeData.removeIndividualVault = await this.removeIndividualVault(); break; } @@ -501,7 +506,7 @@ export default class NotificationBackground { const queueMessage: NotificationQueueMessageItem = { domain, wasVaultLocked, - type: NotificationQueueMessageType.AtRiskPassword, + type: NotificationType.AtRiskPassword, passwordChangeUri, organizationName: organization.name, tab: tab, @@ -591,7 +596,7 @@ export default class NotificationBackground { this.removeTabFromNotificationQueue(tab); const launchTimestamp = new Date().getTime(); const message: AddLoginQueueMessage = { - type: NotificationQueueMessageType.AddLogin, + type: NotificationType.AddLogin, username: loginInfo.username, password: loginInfo.password, domain: loginDomain, @@ -716,10 +721,9 @@ export default class NotificationBackground { // remove any old messages for this tab this.removeTabFromNotificationQueue(tab); const launchTimestamp = new Date().getTime(); - const message: AddChangePasswordQueueMessage = { - type: NotificationQueueMessageType.ChangePassword, - cipherId: cipherId, - newPassword: newPassword, + const message: AddChangePasswordNotificationQueueMessage = { + type: NotificationType.ChangePassword, + data: { cipherId: cipherId, newPassword: newPassword }, domain: loginDomain, tab: tab, launchTimestamp, @@ -734,7 +738,7 @@ export default class NotificationBackground { this.removeTabFromNotificationQueue(tab); const launchTimestamp = new Date().getTime(); const message: AddUnlockVaultQueueMessage = { - type: NotificationQueueMessageType.UnlockVault, + type: NotificationType.UnlockVault, domain: loginDomain, tab: tab, launchTimestamp, @@ -804,8 +808,8 @@ export default class NotificationBackground { const queueMessage = this.notificationQueue[i]; if ( queueMessage.tab.id !== tab.id || - (queueMessage.type !== NotificationQueueMessageType.AddLogin && - queueMessage.type !== NotificationQueueMessageType.ChangePassword) + (queueMessage.type !== NotificationType.AddLogin && + queueMessage.type !== NotificationType.ChangePassword) ) { continue; } @@ -818,17 +822,13 @@ export default class NotificationBackground { this.accountService.activeAccount$.pipe(getOptionalUserId), ); - if (queueMessage.type === NotificationQueueMessageType.ChangePassword) { - const cipherView = await this.getDecryptedCipherById(queueMessage.cipherId, activeUserId); + if (queueMessage.type === NotificationType.ChangePassword) { + const { + data: { cipherId, newPassword }, + } = queueMessage; + const cipherView = await this.getDecryptedCipherById(cipherId, activeUserId); - await this.updatePassword( - cipherView, - queueMessage.newPassword, - edit, - tab, - activeUserId, - skipReprompt, - ); + await this.updatePassword(cipherView, newPassword, edit, tab, activeUserId, skipReprompt); return; } @@ -993,7 +993,7 @@ export default class NotificationBackground { const queueItem = this.notificationQueue.find((item) => item.tab.id === senderTab.id); - if (queueItem?.type === NotificationQueueMessageType.AddLogin) { + if (queueItem?.type === NotificationType.AddLogin) { const cipherView = this.convertAddLoginQueueMessageToCipherView(queueItem); cipherView.organizationId = organizationId; cipherView.folderId = folder; @@ -1075,10 +1075,7 @@ export default class NotificationBackground { private async saveNever(tab: chrome.tabs.Tab) { for (let i = this.notificationQueue.length - 1; i >= 0; i--) { const queueMessage = this.notificationQueue[i]; - if ( - queueMessage.tab.id !== tab.id || - queueMessage.type !== NotificationQueueMessageType.AddLogin - ) { + if (queueMessage.tab.id !== tab.id || queueMessage.type !== NotificationType.AddLogin) { continue; } diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts index 4027689f014..617275da060 100644 --- a/apps/browser/src/autofill/background/overlay.background.ts +++ b/apps/browser/src/autofill/background/overlay.background.ts @@ -1866,7 +1866,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { frameId: this.focusedFieldData.frameId || 0, }, ); - }, 150); + }, 300); } /** diff --git a/apps/browser/src/autofill/enums/notification-queue-message-type.enum.ts b/apps/browser/src/autofill/enums/notification-queue-message-type.enum.ts deleted file mode 100644 index 1fe6246f8b8..00000000000 --- a/apps/browser/src/autofill/enums/notification-queue-message-type.enum.ts +++ /dev/null @@ -1,11 +0,0 @@ -const NotificationQueueMessageType = { - AddLogin: "add", - ChangePassword: "change", - UnlockVault: "unlock", - AtRiskPassword: "at-risk-password", -} as const; - -type NotificationQueueMessageTypes = - (typeof NotificationQueueMessageType)[keyof typeof NotificationQueueMessageType]; - -export { NotificationQueueMessageType, NotificationQueueMessageTypes }; diff --git a/apps/browser/src/autofill/enums/notification-type.enum.ts b/apps/browser/src/autofill/enums/notification-type.enum.ts new file mode 100644 index 00000000000..a82adcea402 --- /dev/null +++ b/apps/browser/src/autofill/enums/notification-type.enum.ts @@ -0,0 +1,10 @@ +const NotificationType = { + AddLogin: "add", + ChangePassword: "change", + UnlockVault: "unlock", + AtRiskPassword: "at-risk-password", +} as const; + +type NotificationTypes = (typeof NotificationType)[keyof typeof NotificationType]; + +export { NotificationType, NotificationTypes }; diff --git a/apps/browser/src/autofill/notification/abstractions/notification-bar.ts b/apps/browser/src/autofill/notification/abstractions/notification-bar.ts index 934aa4a2571..7881d2f1cac 100644 --- a/apps/browser/src/autofill/notification/abstractions/notification-bar.ts +++ b/apps/browser/src/autofill/notification/abstractions/notification-bar.ts @@ -14,6 +14,10 @@ const NotificationTypes = { AtRiskPassword: "at-risk-password", } as const; +/** + * @todo Deprecate in favor of apps/browser/src/autofill/enums/notification-type.enum.ts + * - Determine fix or workaround for restricted imports of that file. + */ type NotificationType = (typeof NotificationTypes)[keyof typeof NotificationTypes]; type NotificationTaskInfo = { @@ -21,6 +25,9 @@ type NotificationTaskInfo = { remainingTasksCount: number; }; +/** + * @todo Use generics to make this type specific to notification types, see Standard_NotificationQueueMessage. + */ type NotificationBarIframeInitData = { ciphers?: NotificationCipherData[]; folders?: FolderView[]; diff --git a/apps/browser/src/autofill/services/autofill.service.ts b/apps/browser/src/autofill/services/autofill.service.ts index 099f345cb75..fd707ef96b3 100644 --- a/apps/browser/src/autofill/services/autofill.service.ts +++ b/apps/browser/src/autofill/services/autofill.service.ts @@ -2459,22 +2459,23 @@ export default class AutofillService implements AutofillServiceInterface { break; } + const includesUsernameFieldName = + this.findMatchingFieldIndex(f, AutoFillConstants.UsernameFieldNames) > -1; + if ( !f.disabled && (canBeReadOnly || !f.readonly) && - (withoutForm || f.form === passwordField.form) && + (withoutForm || f.form === passwordField.form || includesUsernameFieldName) && (canBeHidden || f.viewable) && (f.type === "text" || f.type === "email" || f.type === "tel") ) { usernameField = f; - - if (this.findMatchingFieldIndex(f, AutoFillConstants.UsernameFieldNames) > -1) { - // We found an exact match. No need to keep looking. + // We found an exact match. No need to keep looking. + if (includesUsernameFieldName) { break; } } } - return usernameField; } diff --git a/apps/browser/src/popup/tabs-v2.component.ts b/apps/browser/src/popup/tabs-v2.component.ts index 3d93f5d4e04..860b71794ff 100644 --- a/apps/browser/src/popup/tabs-v2.component.ts +++ b/apps/browser/src/popup/tabs-v2.component.ts @@ -1,11 +1,9 @@ import { Component } from "@angular/core"; -import { combineLatest, map, Observable, startWith, switchMap } from "rxjs"; +import { map, Observable, startWith, switchMap } from "rxjs"; import { NudgesService } from "@bitwarden/angular/vault"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { Icons } from "@bitwarden/components"; import { NavButton } from "../platform/popup/layout/popup-tab-navigation.component"; @@ -19,12 +17,9 @@ export class TabsV2Component { private hasActiveBadges$ = this.accountService.activeAccount$ .pipe(getUserId) .pipe(switchMap((userId) => this.nudgesService.hasActiveBadges$(userId))); - protected navButtons$: Observable = combineLatest([ - this.configService.getFeatureFlag$(FeatureFlag.PM8851_BrowserOnboardingNudge), - this.hasActiveBadges$, - ]).pipe( - startWith([false, false]), - map(([onboardingFeatureEnabled, hasBadges]) => { + protected navButtons$: Observable = this.hasActiveBadges$.pipe( + startWith(false), + map((hasBadges) => { return [ { label: "vault", @@ -49,7 +44,7 @@ export class TabsV2Component { page: "/tabs/settings", icon: Icons.SettingsInactive, iconActive: Icons.SettingsActive, - showBerry: onboardingFeatureEnabled && hasBadges, + showBerry: hasBadges, }, ]; }), @@ -57,6 +52,5 @@ export class TabsV2Component { constructor( private nudgesService: NudgesService, private accountService: AccountService, - private readonly configService: ConfigService, ) {} } diff --git a/apps/browser/src/tools/popup/settings/about-page/about-page-v2.component.html b/apps/browser/src/tools/popup/settings/about-page/about-page-v2.component.html index 839681889a8..9bba3994357 100644 --- a/apps/browser/src/tools/popup/settings/about-page/about-page-v2.component.html +++ b/apps/browser/src/tools/popup/settings/about-page/about-page-v2.component.html @@ -23,12 +23,6 @@ - - - {{ "moreFromBitwarden" | i18n }} - - -